📄 mgcintrbox3frustum.cpp
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement. The various license agreements may be found at
// the Magic Software web site. This file is subject to the license
//
// FREE SOURCE CODE
// http://www.magic-software.com/License/free.pdf
#include "MgcIntrBox3Frustum.h"
//----------------------------------------------------------------------------
bool MgcTestIntersection (const MgcBox3& rkBox, const MgcFrustum& rkFrustum)
{
// for convenience
const MgcVector3* akA = rkBox.Axes();
const MgcReal* afE = rkBox.Extents();
MgcVector3 kDiff = rkBox.Center() - rkFrustum.Origin();
MgcReal afA[3], afB[3], afC[3], afD[3];
MgcReal afNA[3], afNB[3], afNC[3], afND[3];
MgcReal afNApLC[3], afNAmLC[3], afNBpUC[3], afNBmUC[3];
MgcReal afLC[3], afLD[3], afUC[3], afUD[3], afLBpUA[3], afLBmUA[3];
MgcReal fDdD, fR, fP, fMin, fMax, fMTwoLF, fMTwoUF, fLB, fUA, fTmp;
int i, j;
// M = D
afD[2] = kDiff.Dot(rkFrustum.DVector());
for (i = 0; i < 3; i++)
afC[i] = akA[i].Dot(rkFrustum.DVector());
fR = afE[0]*MgcMath::Abs(afC[0]) +
afE[1]*MgcMath::Abs(afC[1]) +
afE[2]*MgcMath::Abs(afC[2]);
if ( afD[2] + fR < rkFrustum.DMin() || afD[2] - fR > rkFrustum.DMax() )
return false;
// M = n*L - l*D
for (i = 0; i < 3; i++)
{
afA[i] = akA[i].Dot(rkFrustum.LVector());
afLC[i] = rkFrustum.LBound()*afC[i];
afNA[i] = rkFrustum.DMin()*afA[i];
afNAmLC[i] = afNA[i] - afLC[i];
}
afD[0] = kDiff.Dot(rkFrustum.LVector());
fR = afE[0]*MgcMath::Abs(afNAmLC[0]) +
afE[1]*MgcMath::Abs(afNAmLC[1]) +
afE[2]*MgcMath::Abs(afNAmLC[2]);
afND[0] = rkFrustum.DMin()*afD[0];
afLD[2] = rkFrustum.LBound()*afD[2];
fDdD = afND[0] - afLD[2];
fMTwoLF = rkFrustum.GetMTwoLF();
if ( fDdD + fR < fMTwoLF || fDdD > fR )
return false;
// M = -n*L - l*D
for (i = 0; i < 3; i++)
afNApLC[i] = afNA[i] + afLC[i];
fR = afE[0]*MgcMath::Abs(afNApLC[0]) +
afE[1]*MgcMath::Abs(afNApLC[1]) +
afE[2]*MgcMath::Abs(afNApLC[2]);
fDdD = -(afND[0] + afLD[2]);
if ( fDdD + fR < fMTwoLF || fDdD > fR )
return false;
// M = n*U - u*D
for (i = 0; i < 3; i++)
{
afB[i] = akA[i].Dot(rkFrustum.UVector());
afUC[i] = rkFrustum.UBound()*afC[i];
afNB[i] = rkFrustum.DMin()*afB[i];
afNBmUC[i] = afNB[i] - afUC[i];
}
afD[1] = kDiff.Dot(rkFrustum.UVector());
fR = afE[0]*MgcMath::Abs(afNBmUC[0]) +
afE[1]*MgcMath::Abs(afNBmUC[1]) +
afE[2]*MgcMath::Abs(afNBmUC[2]);
afND[1] = rkFrustum.DMin()*afD[1];
afUD[2] = rkFrustum.UBound()*afD[2];
fDdD = afND[1] - afUD[2];
fMTwoUF = rkFrustum.GetMTwoUF();
if ( fDdD + fR < fMTwoUF || fDdD > fR )
return false;
// M = -n*U - u*D
for (i = 0; i < 3; i++)
afNBpUC[i] = afNB[i] + afUC[i];
fR = afE[0]*MgcMath::Abs(afNBpUC[0]) +
afE[1]*MgcMath::Abs(afNBpUC[1]) +
afE[2]*MgcMath::Abs(afNBpUC[2]);
fDdD = -(afND[1] + afUD[2]);
if ( fDdD + fR < fMTwoUF || fDdD > fR )
return false;
// M = A[i]
for (i = 0; i < 3; i++)
{
fP = rkFrustum.LBound()*MgcMath::Abs(afA[i]) +
rkFrustum.UBound()*MgcMath::Abs(afB[i]);
afNC[i] = rkFrustum.DMin()*afC[i];
fMin = afNC[i] - fP;
if ( fMin < 0.0 )
fMin *= rkFrustum.GetDRatio();
fMax = afNC[i] + fP;
if ( fMax > 0.0 )
fMax *= rkFrustum.GetDRatio();
fDdD = afA[i]*afD[0] + afB[i]*afD[1] + afC[i]*afD[2];
if ( fDdD + afE[i] < fMin || fDdD - afE[i] > fMax )
return false;
}
// M = Cross(L,A[i])
for (i = 0; i < 3; i++)
{
fP = rkFrustum.UBound()*MgcMath::Abs(afC[i]);
fMin = afNB[i] - fP;
if ( fMin < 0.0 )
fMin *= rkFrustum.GetDRatio();
fMax = afNB[i] + fP;
if ( fMax > 0.0 )
fMax *= rkFrustum.GetDRatio();
fDdD = -afC[i]*afD[1] + afB[i]*afD[2];
fR = afE[0]*MgcMath::Abs(afB[i]*afC[0]-afB[0]*afC[i]) +
afE[1]*MgcMath::Abs(afB[i]*afC[1]-afB[1]*afC[i]) +
afE[2]*MgcMath::Abs(afB[i]*afC[2]-afB[2]*afC[i]);
if ( fDdD + fR < fMin || fDdD - fR > fMax )
return false;
}
// M = Cross(U,A[i])
for (i = 0; i < 3; i++)
{
fP = rkFrustum.LBound()*MgcMath::Abs(afC[i]);
fMin = -afNA[i] - fP;
if ( fMin < 0.0 )
fMin *= rkFrustum.GetDRatio();
fMax = -afNA[i] + fP;
if ( fMax > 0.0 )
fMax *= rkFrustum.GetDRatio();
fDdD = afC[i]*afD[0] - afA[i]*afD[2];
fR = afE[0]*MgcMath::Abs(afA[i]*afC[0]-afA[0]*afC[i]) +
afE[1]*MgcMath::Abs(afA[i]*afC[1]-afA[1]*afC[i]) +
afE[2]*MgcMath::Abs(afA[i]*afC[2]-afA[2]*afC[i]);
if ( fDdD + fR < fMin || fDdD - fR > fMax )
return false;
}
// M = Cross(n*D+l*L+u*U,A[i])
for (i = 0; i < 3; i++)
{
fLB = rkFrustum.LBound()*afB[i];
fUA = rkFrustum.UBound()*afA[i];
afLBpUA[i] = fLB + fUA;
afLBmUA[i] = fLB - fUA;
}
for (i = 0; i < 3; i++)
{
fP = rkFrustum.LBound()*MgcMath::Abs(afNBmUC[i]) +
rkFrustum.UBound()*MgcMath::Abs(afNAmLC[i]);
fTmp = rkFrustum.DMin()*afLBmUA[i];
fMin = fTmp - fP;
if ( fMin < 0.0 )
fMin *= rkFrustum.GetDRatio();
fMax = fTmp + fP;
if ( fMax > 0.0 )
fMax *= rkFrustum.GetDRatio();
fDdD = -afD[0]*afNBmUC[i] + afD[1]*afNAmLC[i] + afD[2]*afLBmUA[i];
fR = 0.0;
for (j = 0; j < 3; j++)
{
fR += afE[j]*MgcMath::Abs(-afA[j]*afNBmUC[i]+ afB[j]*afNAmLC[i]
+ afC[j]*afLBmUA[i]);
}
if ( fDdD + fR < fMin || fDdD - fR > fMax )
return false;
}
// M = Cross(n*D+l*L-u*U,A[i])
for (i = 0; i < 3; i++)
{
fP = rkFrustum.LBound()*MgcMath::Abs(afNBpUC[i]) +
rkFrustum.UBound()*MgcMath::Abs(afNAmLC[i]);
fTmp = rkFrustum.DMin()*afLBpUA[i];
fMin = fTmp - fP;
if ( fMin < 0.0 )
fMin *= rkFrustum.GetDRatio();
fMax = fTmp + fP;
if ( fMax > 0.0 )
fMax *= rkFrustum.GetDRatio();
fDdD = -afD[0]*afNBpUC[i] + afD[1]*afNAmLC[i] + afD[2]*afLBpUA[i];
fR = 0.0;
for (j = 0; j < 3; j++)
{
fR += afE[j]*MgcMath::Abs(-afA[j]*afNBpUC[i]+ afB[j]*afNAmLC[i]
+ afC[j]*afLBpUA[i]);
}
if ( fDdD + fR < fMin || fDdD - fR > fMax )
return false;
}
// M = Cross(n*D-l*L+u*U,A[i])
for (i = 0; i < 3; i++)
{
fP = rkFrustum.LBound()*MgcMath::Abs(afNBmUC[i]) +
rkFrustum.UBound()*MgcMath::Abs(afNApLC[i]);
fTmp = -rkFrustum.DMin()*afLBpUA[i];
fMin = fTmp - fP;
if ( fMin < 0.0 )
fMin *= rkFrustum.GetDRatio();
fMax = fTmp + fP;
if ( fMax > 0.0 )
fMax *= rkFrustum.GetDRatio();
fDdD = -afD[0]*afNBmUC[i] + afD[1]*afNApLC[i] - afD[2]*afLBpUA[i];
fR = 0.0;
for (j = 0; j < 3; j++)
{
fR += afE[j]*MgcMath::Abs(-afA[j]*afNBmUC[i]+ afB[j]*afNApLC[i]
- afC[j]*afLBpUA[i]);
}
if ( fDdD + fR < fMin || fDdD - fR > fMax )
return false;
}
// M = Cross(n*D-l*L-u*U,A[i])
for (i = 0; i < 3; i++)
{
fP = rkFrustum.LBound()*MgcMath::Abs(afNBpUC[i]) +
rkFrustum.UBound()*MgcMath::Abs(afNApLC[i]);
fTmp = -rkFrustum.DMin()*afLBmUA[i];
fMin = fTmp - fP;
if ( fMin < 0.0 )
fMin *= rkFrustum.GetDRatio();
fMax = fTmp + fP;
if ( fMax > 0.0 )
fMax *= rkFrustum.GetDRatio();
fDdD = -afD[0]*afNBpUC[i] + afD[1]*afNApLC[i] - afD[2]*afLBmUA[i];
fR = 0.0;
for (j = 0; j < 3; j++)
{
fR += afE[j]*MgcMath::Abs(-afA[j]*afNBpUC[i]+ afB[j]*afNApLC[i]
- afC[j]*afLBmUA[i]);
}
if ( fDdD + fR < fMin || fDdD - fR > fMax )
return false;
}
return true;
}
//----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -