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

📄 wmldistlin3tri3.cpp

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

        kTriSeg.Direction() = rkTri.Edge1();
        fSqrDist0 = SqrDistance(rkSeg,kTriSeg,&fR0,&fT0);
        fS0 = (Real)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 = SqrDistance(rkSeg,kTriSeg,&fR0,&fT0);
        fS0 = (Real)1.0-fT0;
        if ( fSqrDist0 < fSqrDist )
        {
            fSqrDist = fSqrDist0;
            fR = fR0;
            fS = fS0;
            fT = fT0;
        }

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

        kPt = rkSeg.Origin()+rkSeg.Direction();
        fSqrDist0 = SqrDistance(kPt,rkTri,&fS0,&fT0);
        fR0 = (Real)1.0;
        if ( fSqrDist0 < fSqrDist )
        {
            fSqrDist = fSqrDist0;
            fR = fR0;
            fS = fS0;
            fT = fT0;
        }
    }

    if ( pfSegP )
        *pfSegP = fR;

    if ( pfTriP0 )
        *pfTriP0 = fS;

    if ( pfTriP1 )
        *pfTriP1 = fT;

    return fSqrDist;
}
//----------------------------------------------------------------------------
template <class Real>
Real Wml::Distance (const Line3<Real>& rkLine, const Triangle3<Real>& rkTri,
    Real* pfLinP, Real* pfTriP0, Real* pfTriP1)
{
    return Math<Real>::Sqrt(SqrDistance(rkLine,rkTri,pfLinP,pfTriP0,pfTriP1));
}
//----------------------------------------------------------------------------
template <class Real>
Real Wml::Distance (const Ray3<Real>& rkRay, const Triangle3<Real>& rkTri,
    Real* pfRayP, Real* pfTriP0, Real* pfTriP1)
{
    return Math<Real>::Sqrt(SqrDistance(rkRay,rkTri,pfRayP,pfTriP0,pfTriP1));
}
//----------------------------------------------------------------------------
template <class Real>
Real Wml::Distance (const Segment3<Real>& rkSeg, const Triangle3<Real>& rkTri,
    Real* pfSegP, Real* pfTriP0, Real* pfTriP1)
{
    return Math<Real>::Sqrt(SqrDistance(rkSeg,rkTri,pfSegP,pfTriP0,pfTriP1));
}
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
// explicit instantiation
//----------------------------------------------------------------------------
namespace Wml
{
template WML_ITEM float SqrDistance<float> (const Line3<float>&,
    const Triangle3<float>&, float*, float*, float*);
template WML_ITEM float SqrDistance<float> (const Ray3<float>&,
    const Triangle3<float>&, float*, float*, float*);
template WML_ITEM float SqrDistance<float> (const Segment3<float>&,
    const Triangle3<float>&, float*, float*, float*);
template WML_ITEM float Distance<float> (const Line3<float>&,
    const Triangle3<float>&, float*, float*, float*);
template WML_ITEM float Distance<float> (const Ray3<float>&,
    const Triangle3<float>&, float*, float*, float*);
template WML_ITEM float Distance<float> (const Segment3<float>&,
    const Triangle3<float>&, float*, float*, float*);

template WML_ITEM double SqrDistance<double> (const Line3<double>&,
    const Triangle3<double>&, double*, double*, double*);
template WML_ITEM double SqrDistance<double> (const Ray3<double>&,
    const Triangle3<double>&, double*, double*, double*);
template WML_ITEM double SqrDistance<double> (const Segment3<double>&,
    const Triangle3<double>&, double*, double*, double*);
template WML_ITEM double Distance<double> (const Line3<double>&,
    const Triangle3<double>&, double*, double*, double*);
template WML_ITEM double Distance<double> (const Ray3<double>&,
    const Triangle3<double>&, double*, double*, double*);
template WML_ITEM double Distance<double> (const Segment3<double>&,
    const Triangle3<double>&, double*, double*, double*);
}
//----------------------------------------------------------------------------

⌨️ 快捷键说明

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