📄 ogreopcodeline.cpp
字号:
kPpE[i2]*kPpE[i2] + fDelta*fParam;
if ( pfLParam )
{
*pfLParam = fParam;
rkPnt[i0] = rkBox.getExtents()[i0];
rkPnt[i1] = rkBox.getExtents()[i1];
rkPnt[i2] = -rkBox.getExtents()[i2];
}
}
}
}
else
{
if ( rkDir[i0]*kPpE[i2] >= rkDir[i2]*rkPmE[i0] )
{
// v[i1] < -e[i1], v[i2] >= -e[i2]
fLSqr = rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1];
fTmp = fLSqr*kPpE[i2] - rkDir[i2]*(rkDir[i0]*rkPmE[i0] +
rkDir[i1]*kPpE[i1]);
if ( fTmp <= (2.0)*fLSqr*rkBox.getExtents()[i2] )
{
fT = fTmp/fLSqr;
fLSqr += rkDir[i2]*rkDir[i2];
fTmp = kPpE[i2] - fT;
fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] +
rkDir[i2]*fTmp;
fParam = -fDelta/fLSqr;
rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] +
fTmp*fTmp + fDelta*fParam;
if ( pfLParam )
{
*pfLParam = fParam;
rkPnt[i0] = rkBox.getExtents()[i0];
rkPnt[i1] = -rkBox.getExtents()[i1];
rkPnt[i2] = fT - rkBox.getExtents()[i2];
}
}
else
{
fLSqr += rkDir[i2]*rkDir[i2];
fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] +
rkDir[i2]*rkPmE[i2];
fParam = -fDelta/fLSqr;
rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] +
rkPmE[i2]*rkPmE[i2] + fDelta*fParam;
if ( pfLParam )
{
*pfLParam = fParam;
rkPnt[i0] = rkBox.getExtents()[i0];
rkPnt[i1] = -rkBox.getExtents()[i1];
rkPnt[i2] = rkBox.getExtents()[i2];
}
}
}
else
{
// v[i1] < -e[i1], v[i2] < -e[i2]
fLSqr = rkDir[i0]*rkDir[i0]+rkDir[i2]*rkDir[i2];
fTmp = fLSqr*kPpE[i1] - rkDir[i1]*(rkDir[i0]*rkPmE[i0] +
rkDir[i2]*kPpE[i2]);
if ( fTmp >= 0.0 )
{
// v[i1]-edge is closest
if ( fTmp <= 2.0*fLSqr*rkBox.getExtents()[i1] )
{
fT = fTmp/fLSqr;
fLSqr += rkDir[i1]*rkDir[i1];
fTmp = kPpE[i1] - fT;
fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*fTmp +
rkDir[i2]*kPpE[i2];
fParam = -fDelta/fLSqr;
rfSqrDistance += rkPmE[i0]*rkPmE[i0] + fTmp*fTmp +
kPpE[i2]*kPpE[i2] + fDelta*fParam;
if ( pfLParam )
{
*pfLParam = fParam;
rkPnt[i0] = rkBox.getExtents()[i0];
rkPnt[i1] = fT - rkBox.getExtents()[i1];
rkPnt[i2] = -rkBox.getExtents()[i2];
}
}
else
{
fLSqr += rkDir[i1]*rkDir[i1];
fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*rkPmE[i1] +
rkDir[i2]*kPpE[i2];
fParam = -fDelta/fLSqr;
rfSqrDistance += rkPmE[i0]*rkPmE[i0] + rkPmE[i1]*rkPmE[i1]
+ kPpE[i2]*kPpE[i2] + fDelta*fParam;
if ( pfLParam )
{
*pfLParam = fParam;
rkPnt[i0] = rkBox.getExtents()[i0];
rkPnt[i1] = rkBox.getExtents()[i1];
rkPnt[i2] = -rkBox.getExtents()[i2];
}
}
return;
}
fLSqr = rkDir[i0]*rkDir[i0] + rkDir[i1]*rkDir[i1];
fTmp = fLSqr*kPpE[i2] - rkDir[i2]*(rkDir[i0]*rkPmE[i0] +
rkDir[i1]*kPpE[i1]);
if ( fTmp >= 0.0 )
{
// v[i2]-edge is closest
if ( fTmp <= 2.0*fLSqr*rkBox.getExtents()[i2] )
{
fT = fTmp/fLSqr;
fLSqr += rkDir[i2]*rkDir[i2];
fTmp = kPpE[i2] - fT;
fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] +
rkDir[i2]*fTmp;
fParam = -fDelta/fLSqr;
rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] +
fTmp*fTmp + fDelta*fParam;
if ( pfLParam )
{
*pfLParam = fParam;
rkPnt[i0] = rkBox.getExtents()[i0];
rkPnt[i1] = -rkBox.getExtents()[i1];
rkPnt[i2] = fT - rkBox.getExtents()[i2];
}
}
else
{
fLSqr += rkDir[i2]*rkDir[i2];
fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] +
rkDir[i2]*rkPmE[i2];
fParam = -fDelta/fLSqr;
rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] +
rkPmE[i2]*rkPmE[i2] + fDelta*fParam;
if ( pfLParam )
{
*pfLParam = fParam;
rkPnt[i0] = rkBox.getExtents()[i0];
rkPnt[i1] = -rkBox.getExtents()[i1];
rkPnt[i2] = rkBox.getExtents()[i2];
}
}
return;
}
// (v[i1],v[i2])-corner is closest
fLSqr += rkDir[i2]*rkDir[i2];
fDelta = rkDir[i0]*rkPmE[i0] + rkDir[i1]*kPpE[i1] +
rkDir[i2]*kPpE[i2];
fParam = -fDelta/fLSqr;
rfSqrDistance += rkPmE[i0]*rkPmE[i0] + kPpE[i1]*kPpE[i1] +
kPpE[i2]*kPpE[i2] + fDelta*fParam;
if ( pfLParam )
{
*pfLParam = fParam;
rkPnt[i0] = rkBox.getExtents()[i0];
rkPnt[i1] = -rkBox.getExtents()[i1];
rkPnt[i2] = -rkBox.getExtents()[i2];
}
}
}
}
//----------------------------------------------------------------------------
static void CaseNoZeros (Vector3& rkPnt, const Vector3& rkDir,
const OrientedBox& rkBox, Real* pfLParam, Real& rfSqrDistance)
{
Vector3 kPmE(
rkPnt.x - rkBox.getExtents()[0],
rkPnt.y - rkBox.getExtents()[1],
rkPnt.z - rkBox.getExtents()[2]);
Real fProdDxPy = rkDir.x*kPmE.y;
Real fProdDyPx = rkDir.y*kPmE.x;
Real fProdDzPx, fProdDxPz, fProdDzPy, fProdDyPz;
if ( fProdDyPx >= fProdDxPy )
{
fProdDzPx = rkDir.z*kPmE.x;
fProdDxPz = rkDir.x*kPmE.z;
if ( fProdDzPx >= fProdDxPz )
{
// line intersects x = e0
Face(0,1,2,rkPnt,rkDir,rkBox,kPmE,pfLParam,rfSqrDistance);
}
else
{
// line intersects z = e2
Face(2,0,1,rkPnt,rkDir,rkBox,kPmE,pfLParam,rfSqrDistance);
}
}
else
{
fProdDzPy = rkDir.z*kPmE.y;
fProdDyPz = rkDir.y*kPmE.z;
if ( fProdDzPy >= fProdDyPz )
{
// line intersects y = e1
Face(1,2,0,rkPnt,rkDir,rkBox,kPmE,pfLParam,rfSqrDistance);
}
else
{
// line intersects z = e2
Face(2,0,1,rkPnt,rkDir,rkBox,kPmE,pfLParam,rfSqrDistance);
}
}
}
//----------------------------------------------------------------------------
static void Case0 (int i0, int i1, int i2, Vector3& rkPnt,
const Vector3& rkDir, const OrientedBox& rkBox, Real* pfLParam,
Real& rfSqrDistance)
{
Real fPmE0 = rkPnt[i0] - rkBox.getExtents()[i0];
Real fPmE1 = rkPnt[i1] - rkBox.getExtents()[i1];
Real fProd0 = rkDir[i1]*fPmE0;
Real fProd1 = rkDir[i0]*fPmE1;
Real fDelta, fInvLSqr, fInv;
if ( fProd0 >= fProd1 )
{
// line intersects P[i0] = e[i0]
rkPnt[i0] = rkBox.getExtents()[i0];
Real fPpE1 = rkPnt[i1] + rkBox.getExtents()[i1];
fDelta = fProd0 - rkDir[i0]*fPpE1;
if ( fDelta >= (Real)0.0 )
{
fInvLSqr = ((Real)1.0)/(rkDir[i0]*rkDir[i0]+rkDir[i1]*rkDir[i1]);
rfSqrDistance += fDelta*fDelta*fInvLSqr;
if ( pfLParam )
{
rkPnt[i1] = -rkBox.getExtents()[i1];
*pfLParam = -(rkDir[i0]*fPmE0+rkDir[i1]*fPpE1)*fInvLSqr;
}
}
else
{
if ( pfLParam )
{
fInv = ((Real)1.0)/rkDir[i0];
rkPnt[i1] -= fProd0*fInv;
*pfLParam = -fPmE0*fInv;
}
}
}
else
{
// line intersects P[i1] = e[i1]
rkPnt[i1] = rkBox.getExtents()[i1];
Real fPpE0 = rkPnt[i0] + rkBox.getExtents()[i0];
fDelta = fProd1 - rkDir[i1]*fPpE0;
if ( fDelta >= (Real)0.0 )
{
fInvLSqr = ((Real)1.0)/(rkDir[i0]*rkDir[i0]+rkDir[i1]*rkDir[i1]);
rfSqrDistance += fDelta*fDelta*fInvLSqr;
if ( pfLParam )
{
rkPnt[i0] = -rkBox.getExtents()[i0];
*pfLParam = -(rkDir[i0]*fPpE0+rkDir[i1]*fPmE1)*fInvLSqr;
}
}
else
{
if ( pfLParam )
{
fInv = ((Real)1.0)/rkDir[i1];
rkPnt[i0] -= fProd1*fInv;
*pfLParam = -fPmE1*fInv;
}
}
}
if ( rkPnt[i2] < -rkBox.getExtents()[i2] )
{
fDelta = rkPnt[i2] + rkBox.getExtents()[i2];
rfSqrDistance += fDelta*fDelta;
rkPnt[i2] = -rkBox.getExtents()[i2];
}
else if ( rkPnt[i2] > rkBox.getExtents()[i2] )
{
fDelta = rkPnt[i2] - rkBox.getExtents()[i2];
rfSqrDistance += fDelta*fDelta;
rkPnt[i2] = rkBox.getExtents()[i2];
}
}
//----------------------------------------------------------------------------
static void Case00 (int i0, int i1, int i2, Vector3& rkPnt,
const Vector3& rkDir, const OrientedBox& rkBox, Real* pfLParam,
Real& rfSqrDistance)
{
Real fDelta;
if ( pfLParam )
*pfLParam = (rkBox.getExtents()[i0] - rkPnt[i0])/rkDir[i0];
rkPnt[i0] = rkBox.getExtents()[i0];
if ( rkPnt[i1] < -rkBox.getExtents()[i1] )
{
fDelta = rkPnt[i1] + rkBox.getExtents()[i1];
rfSqrDistance += fDelta*fDelta;
rkPnt[i1] = -rkBox.getExtents()[i1];
}
else if ( rkPnt[i1] > rkBox.getExtents()[i1] )
{
fDelta = rkPnt[i1] - rkBox.getExtents()[i1];
rfSqrDistance += fDelta*fDelta;
rkPnt[i1] = rkBox.getExtents()[i1];
}
if ( rkPnt[i2] < -rkBox.getExtents()[i2] )
{
fDelta = rkPnt[i2] + rkBox.getExtents()[i2];
rfSqrDistance += fDelta*fDelta;
rkPnt[i2] = -rkBox.getExtents()[i2];
}
else if ( rkPnt[i2] > rkBox.getExtents()[i2] )
{
fDelta = rkPnt[i2] - rkBox.getExtents()[i2];
rfSqrDistance += fDelta*fDelta;
rkPnt[i2] = rkBox.getExtents()[i2];
}
}
//----------------------------------------------------------------------------
static void Case000 (Vector3& rkPnt, const OrientedBox& rkBox,
Real& rfSqrDistance)
{
Real fDelta;
if ( rkPnt.x < -rkBox.getExtents()[0] )
{
fDelta = rkPnt.x + rkBox.getExtents()[0];
rfSqrDistance += fDelta*fDelta;
rkPnt.x = -rkBox.getExtents()[0];
}
else if ( rkPnt.x > rkBox.getExtents()[0] )
{
fDelta = rkPnt.x - rkBox.getExtents()[0];
rfSqrDistance += fDelta*fDelta;
rkPnt.x = rkBox.getExtents()[0];
}
if ( rkPnt.y < -rkBox.getExtents()[1] )
{
fDelta = rkPnt.y + rkBox.getExtents()[1];
rfSqrDistance += fDelta*fDelta;
rkPnt.y = -rkBox.getExtents()[1];
}
else if ( rkPnt.y > rkBox.getExtents()[1] )
{
fDelta = rkPnt.y - rkBox.getExtents()[1];
rfSqrDistance += fDelta*fDelta;
rkPnt.y = rkBox.getExtents()[1];
}
if ( rkPnt.z < -rkBox.getExtents()[2] )
{
fDelta = rkPnt.z + rkBox.getExtents()[2];
rfSqrDistance += fDelta*fDelta;
rkPnt.z = -rkBox.getExtents()[2];
}
else if ( rkPnt.z > rkBox.getExtents()[2] )
{
fDelta = rkPnt.z - rkBox.getExtents()[2];
rfSqrDistance += fDelta*fDelta;
rkPnt.z = rkBox.getExtents()[2];
}
}
//---------------------------------------------------------------------
// Distance between a point and a OBB
Real sqrDistance (const Vector3& rkPoint, const OrientedBox& rkBox,
Real* pfBParam0, Real* pfBParam1, Real* pfBParam2)
{
// compute coordinates of point in box coordinate system
Vector3 kDiff = rkPoint - rkBox.getCenter();
Vector3 rot[3] = { rkBox.getOrientation().GetColumn(0),
rkBox.getOrientation().GetColumn(1),
rkBox.getOrientation().GetColumn(2) };
Vector3 kClosest(kDiff | rot[0],
kDiff | rot[1],
kDiff | rot[2]);
// project test point onto box
Real fSqrDistance = (Real)0.0;
Real fDelta;
if ( kClosest.x < -rkBox.getExtents()[0] )
{
fDelta = kClosest.x + rkBox.getExtents()[0];
fSqrDistance += fDelta*fDelta;
kClosest.x = -rkBox.getExtents()[0];
}
else if ( kClosest.x > rkBox.getExtents()[0] )
{
fDelta = kClosest.x - rkBox.getExtents()[0];
fSqrDistance += fDelta*fDelta;
kClosest.x = rkBox.getExtents()[0];
}
if ( kClosest.y < -rkBox.getExtents()[1] )
{
fDelta = kClosest.y + rkBox.getExtents()[1];
fSqrDistance += fDelta*fDelta;
kClosest.y = -rkBox.getExtents()[1];
}
else if ( kClosest.y > rkBox.getExtents()[1] )
{
fDelta = kClosest.y - rkBox.getExtents()[1];
fSqrDistance += fDelta*fDelta;
kClosest.y = rkBox.getExtents()[1];
}
if ( kClosest.z < -rkBox.getExtents()[2] )
{
fDelta = kClosest.z + rkBox.getExtents()[2];
fSqrDistance += fDelta*fDelta;
kClosest.z = -rkBox.getExtents()[2];
}
else if ( kClosest.z > rkBox.getExtents()[2] )
{
fDelta = kClosest.z - rkBox.getExtents()[2];
fSqrDistance += fDelta*fDelta;
kClosest.z = rkBox.getExtents()[2];
}
if ( pfBParam0 ) *pfBParam0 = kClosest.x;
if ( pfBParam1 ) *pfBParam1 = kClosest.y;
if ( pfBParam2 ) *pfBParam2 = kClosest.z;
return fSqrDistance;
}
//---------------------------------------------------------------------
// Distance from an infitine line and a OBB
Real sqrDistance( const Vector3& origin, const Vector3& direction,
const OrientedBox& rkBox, Real* pfLParam, Real* pfBParam0, Real* pfBParam1, Real* pfBParam2)
{
// compute coordinates of line in box coordinate system
Vector3 kDiff = origin - rkBox.getCenter();
Vector3 rot[3] = { rkBox.getOrientation().GetColumn(0),
rkBox.getOrientation().GetColumn(1),
rkBox.getOrientation().GetColumn(2) };
Vector3 kPnt( kDiff | rot[0],
kDiff | rot[1],
kDiff | rot[2] );
Vector3 kDir( direction | rot[0],
direction | rot[1],
direction | rot[2] );
// Apply reflections so that direction vector has nonnegative components.
bool bReflect[3];
int i;
for (i = 0; i < 3; i++)
{
if ( kDir[i] < (Real)0.0 )
{
kPnt[i] = -kPnt[i];
kDir[i] = -kDir[i];
bReflect[i] = true;
}
else
{
bReflect[i] = false;
}
}
Real fSqrDistance = (Real)0.0;
if ( kDir.x > (Real)0.0 )
{
if ( kDir.y > (Real)0.0 )
{
if ( kDir.z > (Real)0.0 )
{
// (+,+,+)
CaseNoZeros(kPnt,kDir,rkBox,pfLParam,fSqrDistance);
}
else
{
// (+,+,0)
Case0(0,1,2,kPnt,kDir,rkBox,pfLParam,fSqrDistance);
}
}
else
{
if ( kDir.z > (Real)0.0 )
{
// (+,0,+)
Case0(0,2,1,kPnt,kDir,rkBox,pfLParam,fSqrDistance);
}
else
{
// (+,0,0)
Case00(0,1,2,kPnt,kDir,rkBox,pfLParam,fSqrDistance);
}
}
}
else
{
if ( kDir.y > (Real)0.0 )
{
if ( kDir.z > (Real)0.0 )
{
// (0,+,+)
Case0(1,2,0,kPnt,kDir,rkBox,pfLParam,fSqrDistance);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -