⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mgcdistlin3tri3.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    {
                        fSqrDist = fSqrDist0;
                        fR = fR0;
                        fS = fS0;
                        fT = fT0;
                    }
                }
                else  // region 1m
                {
                    // min on face s+t=1 or r=0
                    kTriSeg.Origin() = rkTri.Origin()+rkTri.Edge0();
                    kTriSeg.Direction() = rkTri.Edge1()-rkTri.Edge0();
                    fSqrDist = MgcSqrDistance(rkRay,kTriSeg,&fR,&fT);
                    fS = 1.0-fT;
                    fSqrDist0 = MgcSqrDistance(rkRay.Origin(),rkTri,&fS0,
                        &fT0);
                    fR0 = 0.0;
                    if ( fSqrDist0 < fSqrDist )
                    {
                        fSqrDist = fSqrDist0;
                        fR = fR0;
                        fS = fS0;
                        fT = fT0;
                    }
                }
            }
        }
        else  // fR > 0
        {
            if ( fS+fT <= 1.0 )
            {
                if ( fS < 0.0 )
                {
                    if ( fT < 0.0 )  // region 4p
                    {
                        // min on face s=0 or t=0
                        kTriSeg.Origin() = rkTri.Origin();
                        kTriSeg.Direction() = rkTri.Edge1();
                        fSqrDist = MgcSqrDistance(rkRay,kTriSeg,0,&fT);
                        fS = 0.0;
                        kTriSeg.Origin() = rkTri.Origin();
                        kTriSeg.Direction() = rkTri.Edge0();
                        fSqrDist0 = MgcSqrDistance(rkRay,kTriSeg,0,&fS0);
                        fT0 = 0.0;
                        if ( fSqrDist0 < fSqrDist )
                        {
                            fSqrDist = fSqrDist0;
                            fS = fS0;
                            fT = fT0;
                        }
                    }
                    else  // region 3p
                    {
                        // min on face s=0
                        kTriSeg.Origin() = rkTri.Origin();
                        kTriSeg.Direction() = rkTri.Edge1();
                        fSqrDist = MgcSqrDistance(rkRay,kTriSeg,0,&fT);
                        fS = 0.0;
                    }
                }
                else if ( fT < 0.0 )  // region 5p
                {
                    // min on face t=0
                    kTriSeg.Origin() = rkTri.Origin();
                    kTriSeg.Direction() = rkTri.Edge0();
                    fSqrDist = MgcSqrDistance(rkRay,kTriSeg,0,&fS);
                    fT = 0.0;
                }
                else  // region 0p
                {
                    // ray intersects triangle
                    fSqrDist = 0.0;
                }
            }
            else
            {
                if ( fS < 0.0 )  // region 2p
                {
                    // min on face s=0 or s+t=1
                    kTriSeg.Origin() = rkTri.Origin();
                    kTriSeg.Direction() = rkTri.Edge1();
                    fSqrDist = MgcSqrDistance(rkRay,kTriSeg,0,&fT);
                    fS = 0.0;
                    kTriSeg.Origin() = rkTri.Origin()+rkTri.Edge0();
                    kTriSeg.Direction() = rkTri.Edge1()-rkTri.Edge0();
                    fSqrDist0 = MgcSqrDistance(rkRay,kTriSeg,0,&fT0);
                    fS0 = 1.0-fT0;
                    if ( fSqrDist0 < fSqrDist )
                    {
                        fSqrDist = fSqrDist0;
                        fS = fS0;
                        fT = fT0;
                    }
                }
                else if ( fT < 0.0 )  // region 6p
                {
                    // min on face t=0 or s+t=1
                    kTriSeg.Origin() = rkTri.Origin();
                    kTriSeg.Direction() = rkTri.Edge0();
                    fSqrDist = MgcSqrDistance(rkRay,kTriSeg,0,&fS);
                    fT = 0.0;
                    kTriSeg.Origin() = rkTri.Origin()+rkTri.Edge0();
                    kTriSeg.Direction() = rkTri.Edge1()-rkTri.Edge0();
                    fSqrDist0 = MgcSqrDistance(rkRay,kTriSeg,0,&fT0);
                    fS0 = 1.0-fT0;
                    if ( fSqrDist0 < fSqrDist )
                    {
                        fSqrDist = fSqrDist0;
                        fS = fS0;
                        fT = fT0;
                    }
                }
                else  // region 1p
                {
                    // min on face s+t=1
                    kTriSeg.Origin() = rkTri.Origin()+rkTri.Edge0();
                    kTriSeg.Direction() = rkTri.Edge1()-rkTri.Edge0();
                    fSqrDist = MgcSqrDistance(rkRay,kTriSeg,0,&fT);
                    fS = 1.0-fT;
                }
            }
        }
    }
    else
    {
        // ray and triangle are parallel
        kTriSeg.Origin() = rkTri.Origin();
        kTriSeg.Direction() = rkTri.Edge0();
        fSqrDist = MgcSqrDistance(rkRay,kTriSeg,&fR,&fS);
        fT = 0.0;

        kTriSeg.Direction() = rkTri.Edge1();
        fSqrDist0 = MgcSqrDistance(rkRay,kTriSeg,&fR0,&fT0);
        fS0 = 0.0;
        if ( fSqrDist0 < fSqrDist )
        {
            fSqrDist = fSqrDist0;
            fR = fR0;
            fS = fS0;
            fT = fT0;
        }

        kTriSeg.Origin() = rkTri.Origin() + rkTri.Edge0();
        kTriSeg.Direction() = rkTri.Edge1() - rkTri.Edge0();
        fSqrDist0 = MgcSqrDistance(rkRay,kTriSeg,&fR0,&fT0);
        fS0 = 1.0-fT0;
        if ( fSqrDist0 < fSqrDist )
        {
            fSqrDist = fSqrDist0;
            fR = fR0;
            fS = fS0;
            fT = fT0;
        }

        fSqrDist0 = MgcSqrDistance(rkRay.Origin(),rkTri,&fS0,&fT0);
        fR0 = 0.0;
        if ( fSqrDist0 < fSqrDist )
        {
            fSqrDist = fSqrDist0;
            fR = fR0;
            fS = fS0;
            fT = fT0;
        }
    }

    if ( pfRayP )
        *pfRayP = fR;

    if ( pfTriP0 )
        *pfTriP0 = fS;

    if ( pfTriP1 )
        *pfTriP1 = fT;

    return MgcMath::Abs(fSqrDist);
}
//----------------------------------------------------------------------------
MgcReal MgcSqrDistance (const MgcSegment3& rkSeg, const MgcTriangle3& rkTri,
    MgcReal* pfSegP, MgcReal* pfTriP0, MgcReal* pfTriP1)
{    MgcVector3 kDiff = rkTri.Origin() - rkSeg.Origin();    MgcReal fA00 = rkSeg.Direction().SquaredLength();    MgcReal fA01 = -rkSeg.Direction().Dot(rkTri.Edge0());    MgcReal fA02 = -rkSeg.Direction().Dot(rkTri.Edge1());    MgcReal fA11 = rkTri.Edge0().SquaredLength();    MgcReal fA12 = rkTri.Edge0().Dot(rkTri.Edge1());    MgcReal fA22 = rkTri.Edge1().Dot(rkTri.Edge1());    MgcReal fB0  = -kDiff.Dot(rkSeg.Direction());    MgcReal fB1  = kDiff.Dot(rkTri.Edge0());    MgcReal fB2  = kDiff.Dot(rkTri.Edge1());    MgcReal fCof00 = fA11*fA22-fA12*fA12;    MgcReal fCof01 = fA02*fA12-fA01*fA22;    MgcReal fCof02 = fA01*fA12-fA02*fA11;    MgcReal fDet = fA00*fCof00+fA01*fCof01+fA02*fCof02;    MgcSegment3 kTriSeg;    MgcVector3 kPt;    MgcReal fSqrDist, fSqrDist0, fR, fS, fT, fR0, fS0, fT0;    if ( MgcMath::Abs(fDet) >= gs_fTolerance )    {        MgcReal fCof11 = fA00*fA22-fA02*fA02;        MgcReal fCof12 = fA02*fA01-fA00*fA12;        MgcReal fCof22 = fA00*fA11-fA01*fA01;        MgcReal fInvDet = 1.0/fDet;        MgcReal fRhs0 = -fB0*fInvDet;        MgcReal fRhs1 = -fB1*fInvDet;        MgcReal fRhs2 = -fB2*fInvDet;        fR = fCof00*fRhs0+fCof01*fRhs1+fCof02*fRhs2;        fS = fCof01*fRhs0+fCof11*fRhs1+fCof12*fRhs2;        fT = fCof02*fRhs0+fCof12*fRhs1+fCof22*fRhs2;        if ( fR < 0.0 )        {            if ( fS+fT <= 1.0 )            {                if ( fS < 0.0 )                {                    if ( fT < 0.0 )  // region 4m                    {                        // min on face s=0 or t=0 or r=0                        kTriSeg.Origin() = rkTri.Origin();                        kTriSeg.Direction() = rkTri.Edge1();                        fSqrDist = MgcSqrDistance(rkSeg,kTriSeg,&fR,&fT);
                        fS = 0.0;                        kTriSeg.Origin() = rkTri.Origin();                        kTriSeg.Direction() = rkTri.Edge0();                        fSqrDist0 = MgcSqrDistance(rkSeg,kTriSeg,&fR0,&fS0);                        fT0 = 0.0;                        if ( fSqrDist0 < fSqrDist )                        {                            fSqrDist = fSqrDist0;                            fR = fR0;                            fS = fS0;                            fT = fT0;                        }                        fSqrDist0 = MgcSqrDistance(rkSeg.Origin(),rkTri,
                            &fS0,&fT0);                        fR0 = 0.0;                        if ( fSqrDist0 < fSqrDist )                        {                            fSqrDist = fSqrDist0;                            fR = fR0;                            fS = fS0;                            fT = fT0;                        }                    }                    else  // region 3m                    {                        // min on face s=0 or r=0                        kTriSeg.Origin() = rkTri.Origin();                        kTriSeg.Direction() = rkTri.Edge1();                        fSqrDist = MgcSqrDistance(rkSeg,kTriSeg,&fR,&fT);                        fS = 0.0;                        fSqrDist0 = MgcSqrDistance(rkSeg.Origin(),rkTri,
                            &fS0,&fT0);                        fR0 = 0.0;                        if ( fSqrDist0 < fSqrDist )                        {                            fSqrDist = fSqrDist0;                            fR = fR0;                            fS = fS0;                            fT = fT0;                        }                    }                }                else if ( fT < 0.0 )  // region 5m                {                    // min on face t=0 or r=0                    kTriSeg.Origin() = rkTri.Origin();                    kTriSeg.Direction() = rkTri.Edge0();                    fSqrDist = MgcSqrDistance(rkSeg,kTriSeg,&fR,&fS);                    fT = 0.0;                    fSqrDist0 = MgcSqrDistance(rkSeg.Origin(),rkTri,&fS0,
                        &fT0);                    fR0 = 0.0;                    if ( fSqrDist0 < fSqrDist )                    {                        fSqrDist = fSqrDist0;                        fR = fR0;                        fS = fS0;                        fT = fT0;                    }                }                else  // region 0m                {                    // min on face r=0                    fSqrDist = MgcSqrDistance(rkSeg.Origin(),rkTri,&fS,&fT);                    fR = 0.0;                }            }            else            {                if ( fS < 0.0 )  // region 2m                {                    // min on face s=0 or s+t=1 or r=0                    kTriSeg.Origin() = rkTri.Origin();                    kTriSeg.Direction() = rkTri.Edge1();                    fSqrDist = MgcSqrDistance(rkSeg,kTriSeg,&fR,&fT);                    fS = 0.0;                    kTriSeg.Origin() = rkTri.Origin()+rkTri.Edge0();                    kTriSeg.Direction() = rkTri.Edge1()-rkTri.Edge0();                    fSqrDist0 = MgcSqrDistance(rkSeg,kTriSeg,&fR0,&fT0);                    fS0 = 1.0-fT0;                    if ( fSqrDist0 < fSqrDist )                    {                        fSqrDist = fSqrDist0;                        fR = fR0;                        fS = fS0;                        fT = fT0;                    }                    fSqrDist0 = MgcSqrDistance(rkSeg.Origin(),rkTri,&fS0,
                        &fT0);                    fR0 = 0.0;                    if ( fSqrDist0 < fSqrDist )                    {                        fSqrDist = fSqrDist0;                        fR = fR0;                        fS = fS0;                        fT = fT0;                    }                }                else if ( fT < 0.0 )  // region 6m                {                    // min on face t=0 or s+t=1 or r=0                    kTriSeg.Origin() = rkTri.Origin();                    kTriSeg.Direction() = rkTri.Edge0();                    fSqrDist = MgcSqrDistance(rkSeg,kTriSeg,&fR,&fS);                    fT = 0.0;                    kTriSeg.Origin() = rkTri.Origin()+rkTri.Edge0();                    kTriSeg.Direction() = rkTri.Edge1()-rkTri.Edge0();                    fSqrDist0 = MgcSqrDistance(rkSeg,kTriSeg,&fR0,&fT0);                    fS0 = 1.0-fT0;                    if ( fSqrDist0 < fSqrDist )                    {                        fSqrDist = fSqrDist0;                        fR = fR0;                        fS = fS0;                        fT = fT0;                    }                    fSqrDist0 = MgcSqrDistance(rkSeg.Origin(),rkTri,&fS0,
                        &fT0);                    fR0 = 0.0;                    if ( fSqrDist0 < fSqrDist )                    {                        fSqrDist = fSqrDist0;                        fR = fR0;                        fS = fS0;                        fT = fT0;                    }                }                else  // region 1m                {                    // min on face s+t=1 or r=0                    kTriSeg.Origin() = rkTri.Origin()+rkTri.Edge0();                    kTriSeg.Direction() = rkTri.Edge1()-rkTri.Edge0();                    fSqrDist = MgcSqrDistance(rkSeg,kTriSeg,&fR,&fT);                    fS = 1.0-fT;                    fSqrDist0 = MgcSqrDistance(rkSeg.Origin(),rkTri,&fS0,
                        &fT0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -