📄 wmlintrlin3box3.cpp
字号:
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 + -