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

📄 wmlintrlin3box3.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    if ( bIntersects )
    {
        if ( fT0 != fT1 )
        {
            riQuantity = 2;
            akPoint[0] = rkLine.Origin() + fT0*rkLine.Direction();
            akPoint[1] = rkLine.Origin() + fT1*rkLine.Direction();
        }
        else
        {
            riQuantity = 1;
            akPoint[0] = rkLine.Origin() + fT0*rkLine.Direction();
        }
    }
    else
    {
        riQuantity = 0;
    }

    return bIntersects;
}
//----------------------------------------------------------------------------
// moving objects
//----------------------------------------------------------------------------
template <class Real>
static bool SegBoxAxisTest (const Vector3<Real>& rkAxis,
    const Vector3<Real> akU[2], const Vector3<Real>& rkVel,
    const Box3<Real>& rkBox, Real& rfTFirst, Real& rfTLast, Real fTMax)
{
    Real fMin0, fMax0;
    LineProjection(rkAxis,akU,fMin0,fMax0);

    Real fMin1, fMax1;
    BoxProjection(rkAxis,rkBox,fMin1,fMax1);
    
    return AxisTest(rkVel,rkAxis,fMin0,fMax0,fMin1,fMax1,rfTFirst,rfTLast,
        fTMax);
}
//----------------------------------------------------------------------------
template <class Real>
static bool SegBoxAxisFind (const Vector3<Real>& rkAxis,  
    const Vector3<Real>& rkVel, const Vector3<Real> akU[2],
    const Box3<Real>& rkBox, Real& rfTFirst, Real& rfTLast, Real fTMax,
    ContactSide& reSide, ContactConfig<Real>& rkTUC,
    ContactConfig<Real>& rkTVC)
{
    ContactConfig<Real> kUC;
    GetLineConfiguration(rkAxis,akU,kUC);

    ContactConfig<Real> kVC;
    GetBoxConfiguration(rkAxis,rkBox,kVC);

    return AxisFind(rkVel,rkAxis,kUC,kVC,reSide,rkTUC,rkTVC,rfTFirst,rfTLast,
        fTMax);
}
//----------------------------------------------------------------------------
template <class Real>
static void FindContactSet (const Vector3<Real> akU[2],
    const Box3<Real>& rkBox, ContactSide eSide, 
    const ContactConfig<Real>& rkSegContact,
    const ContactConfig<Real>& rkBoxContact,
    const Vector3<Real>& rkSegVelocity, const Vector3<Real>& rkBoxVelocity,
    Real fTFirst, int& riQuantity, Vector3<Real>* akP)
{
    // move segment to new position
    Vector3<Real> akNewSeg[2] =
    {
        akU[0] + fTFirst*rkSegVelocity,
        akU[1] + fTFirst*rkSegVelocity
    };

    // move box to new position
    Box3<Real> kNewBox;
    kNewBox.Center() = rkBox.Center() + fTFirst*rkBoxVelocity;
    for (int i = 0; i < 3; i++)
    {
        kNewBox.Axis(i) = rkBox.Axis(i);
        kNewBox.Extent(i) = rkBox.Extent(i);
    }

    if ( eSide == LEFT )
    {
        // box on left of line
        if ( rkSegContact.m_kMap == m11 )
        {
            riQuantity = 1;
            akP[0] = akNewSeg[rkSegContact.m_aiIndex[0]];
        }
        else if ( rkBoxContact.m_kMap == m1_1 )
        {
            riQuantity = 1;
            akP[0] = GetPoint(rkBoxContact.m_aiIndex[7],kNewBox);
        }
        else if ( rkBoxContact.m_kMap == m2_2 )
        {
            // segment-segment intersection
            Vector3<Real> akBoxSeg[2];
            akBoxSeg[0] = GetPoint(rkBoxContact.m_aiIndex[6],kNewBox);
            akBoxSeg[1] = GetPoint(rkBoxContact.m_aiIndex[7],kNewBox);
            FindContactSetLinLin(akNewSeg,akBoxSeg,riQuantity,akP);
        }
        else // rkBoxContact.m_kMap == m44
        {
            // segment-boxface intersection
            Vector3<Real> akBoxFace[4];
            akBoxFace[0] = GetPoint(rkBoxContact.m_aiIndex[4],kNewBox);
            akBoxFace[1] = GetPoint(rkBoxContact.m_aiIndex[5],kNewBox);
            akBoxFace[2] = GetPoint(rkBoxContact.m_aiIndex[6],kNewBox);
            akBoxFace[3] = GetPoint(rkBoxContact.m_aiIndex[7],kNewBox);
            FindContactSetCoplanarLineRect(akNewSeg,akBoxFace,riQuantity,akP);
        }
    }
    else // eSide == RIGHT 
    {
        // box on right of line
        if ( rkSegContact.m_kMap == m11 )
        {
            riQuantity = 1;
            akP[0] = akNewSeg[rkSegContact.m_aiIndex[1]];
        }
        else if ( rkBoxContact.m_kMap == m1_1 )
        {
            riQuantity = 1;
            akP[0] = GetPoint(rkBoxContact.m_aiIndex[0],kNewBox);
        }
        else if ( rkBoxContact.m_kMap == m2_2 )
        {
            // segment-segment intersection
            Vector3<Real> akBoxSeg[2];
            akBoxSeg[0] = GetPoint(rkBoxContact.m_aiIndex[0],kNewBox);
            akBoxSeg[1] = GetPoint(rkBoxContact.m_aiIndex[1],kNewBox);
            FindContactSetLinLin(akNewSeg,akBoxSeg,riQuantity,akP);
        }
        else // rkBoxContact.m_kMap == m44
        {
            // segment-boxface intersection
            Vector3<Real> akBoxFace[4];
            akBoxFace[0] = GetPoint(rkBoxContact.m_aiIndex[0],kNewBox);
            akBoxFace[1] = GetPoint(rkBoxContact.m_aiIndex[1],kNewBox);
            akBoxFace[2] = GetPoint(rkBoxContact.m_aiIndex[2],kNewBox);
            akBoxFace[3] = GetPoint(rkBoxContact.m_aiIndex[3],kNewBox);
            FindContactSetCoplanarLineRect(akNewSeg,akBoxFace,riQuantity,akP);
        }
     }
}
//----------------------------------------------------------------------------
template <class Real>
bool Wml::TestIntersection (const Segment3<Real>& rkSegment,
    const Vector3<Real>& rkSegVelocity, const Box3<Real>& rkBox,
    const Vector3<Real>& rkBoxVelocity, Real& rfTFirst, Real fTMax)
{
    // get end points of segment
    Vector3<Real> akU[2] =
    {
        rkSegment.Origin(),
        rkSegment.Origin() + rkSegment.Direction()
    };

    // get box velocity relative to segment
    Vector3<Real> kVel = rkBoxVelocity - rkSegVelocity;

    rfTFirst = (Real)0.0;
    Real fTLast = Math<Real>::MAX_REAL;

    int i;
    Vector3<Real> kAxis;

    // test box normals
    for (i = 0; i < 3; i++)
    {
        kAxis = rkBox.Axis(i);
        if ( !SegBoxAxisTest(kAxis,akU,kVel,rkBox,rfTFirst,fTLast,fTMax) )
            return false;
    }

    // test seg-direction cross box-edges
    for (i = 0; i < 3; i++ )
    {
        kAxis = rkBox.Axis(i).Cross(rkSegment.Direction());
        if ( !SegBoxAxisTest(kAxis,akU,kVel,rkBox,rfTFirst,fTLast,fTMax) )
            return false;
    }

    // test velocity cross box-faces
    for (i = 0; i < 3; i++)
    {
        kAxis = kVel.Cross(rkBox.Axis(i));
        if ( !SegBoxAxisTest(kAxis,akU,kVel,rkBox,rfTFirst,fTLast,fTMax) )
            return false;
    }

    return true;
}
//----------------------------------------------------------------------------
template <class Real>
bool Wml::FindIntersection (const Segment3<Real>& rkSegment,
    const Vector3<Real>& rkSegVelocity, const Box3<Real>& rkBox,
    const Vector3<Real>& rkBoxVelocity, Real& rfTFirst, Real fTMax,
    int& riQuantity, Vector3<Real> akP[2])
{
    // get end points of segment
    Vector3<Real> akU[2] =
    {
        rkSegment.Origin(),
        rkSegment.Origin() + rkSegment.Direction()
    };

    // get box velocity relative to segment
    Vector3<Real> kVel = rkBoxVelocity - rkSegVelocity;

    rfTFirst = (Real)0.0;
    Real fTLast = Math<Real>::MAX_REAL;

    int i;
    Vector3<Real> kAxis;
    ContactSide eSide = NONE;
    ContactConfig<Real> kSegContact, kBoxContact;

    // test box normals
    for (i = 0; i < 3; i++)
    {
        kAxis = rkBox.Axis(i);
        if ( !SegBoxAxisFind(kAxis,kVel,akU,rkBox,rfTFirst,fTLast,fTMax,
             eSide,kSegContact,kBoxContact) )
        {
            return false;
        }
    }

    // test seg-direction cross box-edges
    for (i = 0; i < 3; i++ )
    {
        kAxis = rkBox.Axis(i).Cross(rkSegment.Direction());
        if ( !SegBoxAxisFind(kAxis,kVel,akU,rkBox,rfTFirst,fTLast,fTMax,
             eSide,kSegContact,kBoxContact) )
        {
            return false;
        }
    }

    // test velocity cross box-faces
    for (i = 0; i < 3; i++)
    {
        kAxis = kVel.Cross(rkBox.Axis(i));
        if ( !SegBoxAxisFind(kAxis,kVel,akU,rkBox,rfTFirst,fTLast,fTMax,
             eSide,kSegContact,kBoxContact) )
        {
            return false;
        }
    }

    if ( rfTFirst < (Real)0.0 || eSide == NONE )
    {
        // intersecting now
        return false;
    }

    FindContactSet(akU,rkBox,eSide,kSegContact,kBoxContact,rkSegVelocity,
        rkBoxVelocity,rfTFirst,riQuantity,akP);
    return true;
}
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
// explicit instantiation
//----------------------------------------------------------------------------
namespace Wml
{
template WML_ITEM bool TestIntersection<float> (
    const Segment3<float>&, const Box3<float>&);
template WML_ITEM bool TestIntersection<float> (
    const Ray3<float>&, const Box3<float>&);
template WML_ITEM bool TestIntersection<float> (
    const Line3<float>&, const Box3<float>& rkBox);
template WML_ITEM bool FindIntersection<float> (
    const Vector3<float>&, const Vector3<float>&, const float[3],
    float&, float&);
template WML_ITEM bool FindIntersection<float> (
    const Segment3<float>&, const Box3<float>&, int&, Vector3<float>[2]);
template WML_ITEM bool FindIntersection<float> (
    const Ray3<float>&, const Box3<float>&, int&, Vector3<float>[2]);
template WML_ITEM bool FindIntersection<float> (
    const Line3<float>&, const Box3<float>&, int&, Vector3<float>[2]);
template WML_ITEM bool TestIntersection<float> (
    const Segment3<float>&, const Vector3<float>&, const Box3<float>&,
    const Vector3<float>&, float&, float);
template WML_ITEM bool FindIntersection<float> (
    const Segment3<float>&, const Vector3<float>&, const Box3<float>&,
    const Vector3<float>&, float&, float, int&, Vector3<float>[2]);

template WML_ITEM bool TestIntersection<double> (
    const Segment3<double>&, const Box3<double>&);
template WML_ITEM bool TestIntersection<double> (
    const Ray3<double>&, const Box3<double>&);
template WML_ITEM bool TestIntersection<double> (
    const Line3<double>&, const Box3<double>& rkBox);
template WML_ITEM bool FindIntersection<double> (
    const Vector3<double>&, const Vector3<double>&, const double[3],
    double&, double&);
template WML_ITEM bool FindIntersection<double> (
    const Segment3<double>&, const Box3<double>&, int&, Vector3<double>[2]);
template WML_ITEM bool FindIntersection<double> (
    const Ray3<double>&, const Box3<double>&, int&, Vector3<double>[2]);
template WML_ITEM bool FindIntersection<double> (
    const Line3<double>&, const Box3<double>&, int&, Vector3<double>[2]);
template WML_ITEM bool TestIntersection<double> (
    const Segment3<double>&, const Vector3<double>&, const Box3<double>&,
    const Vector3<double>&, double&, double);
template WML_ITEM bool FindIntersection<double> (
    const Segment3<double>&, const Vector3<double>&, const Box3<double>&,
    const Vector3<double>&, double&, double, int&, Vector3<double>[2]);
}
//----------------------------------------------------------------------------

⌨️ 快捷键说明

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