📄 ogreorientedbox.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
/// @file OgreOrientedBox.cpp
/// @brief <TODO: insert file description here>
///
/// @author The OgreOpcode Team @date 28-05-2005
///
///////////////////////////////////////////////////////////////////////////////
///
/// This file is part of OgreOpcode.
///
/// A lot of the code is based on the Nebula Opcode Collision module, see docs/Nebula_license.txt
///
/// OgreOpcode is free software; you can redistribute it and/or
/// modify it under the terms of the GNU Lesser General Public
/// License as published by the Free Software Foundation; either
/// version 2.1 of the License, or (at your option) any later version.
///
/// OgreOpcode is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
/// Lesser General Public License for more details.
///
/// You should have received a copy of the GNU Lesser General Public
/// License along with OgreOpcode; if not, write to the Free Software
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
///
///////////////////////////////////////////////////////////////////////////////
#include "OgreOrientedBox.h"
using namespace Ogre;
namespace OgreOpcode
{
namespace Details
{
//------------------------------------------------------------------------
bool OrientedBox::intersects( const Details::bbox3& box ) const
{
// Optimize this: return intersects( OrientedBox(box) );
//translation, in parent frame (note: A = this, B = obb)
Vector3 v = box.getCenter() - center;
Vector3 boxExtents = box.getExtents();
//translation, in A's frame
Vector3 T( v.dotProduct( rot.GetColumn(0)),
v.dotProduct( rot.GetColumn(1)),
v.dotProduct( rot.GetColumn(2)) );
//B's basis with respect to A's local frame
Real R[3][3];
Real FR[3][3];
Real ra, rb, t;
long i, k;
//calculate rotation matrix from "obb" to "this" - palso recomputes the fabs matrix
for( i=0 ; i<3 ; i++ )
{
for( k=0 ; k<3 ; k++ )
{
R[i][k] = rot.GetColumn(k)[i];
// fabs and shift borrowed from RAPID
FR[i][k] = 1e-6f + Math::Abs(R[i][k]);
}
}
// Separating axis theorem: test of all 15 potential separating axes
// These axes are always parallel to each OBB edges or its normal plane
const Vector3 &a = extents,
&b = boxExtents;
// First stage: each obb's axis!
//A's basis vectors
for( i=0 ; i<3 ; i++ )
{
ra = a[i];
rb = b.x*FR[i][0] + b.y*FR[i][1] + b.z*FR[i][2];
t = Math::Abs( T[i] );
if( t > ra + rb ) return false;
}
//B's basis vectors
for( k=0 ; k<3 ; k++ )
{
ra = a.x*FR[0][k] + a.y*FR[1][k] + a.z*FR[2][k];
rb = b[k];
t = Math::Abs( T[0]*R[0][k] + T[1]*R[1][k] + T[2]*R[2][k] );
if( t > ra + rb ) return false;
}
// Second stage: 9 cross products
//L = A0 x B0
ra = a[1]*FR[2][0] + a[2]*FR[1][0];
rb = b[1]*FR[0][2] + b[2]*FR[0][1];
t = Math::Abs( T[2]*R[1][0] - T[1]*R[2][0] );
if( t > ra + rb ) return false;
//L = A0 x B1
ra = a[1]*FR[2][1] + a[2]*FR[1][1];
rb = b[0]*FR[0][2] + b[2]*FR[0][0];
t = Math::Abs( T[2]*R[1][1] - T[1]*R[2][1] );
if( t > ra + rb ) return false;
//L = A0 x B2
ra = a[1]*FR[2][2] + a[2]*FR[1][2];
rb = b[0]*FR[0][1] + b[1]*FR[0][0];
t = Math::Abs( T[2]*R[1][2] - T[1]*R[2][2] );
if( t > ra + rb ) return false;
//L = A1 x B0
ra = a[0]*FR[2][0] + a[2]*FR[0][0];
rb = b[1]*FR[1][2] + b[2]*FR[1][1];
t = Math::Abs( T[0]*R[2][0] - T[2]*R[0][0] );
if( t > ra + rb ) return false;
//L = A1 x B1
ra = a[0]*FR[2][1] + a[2]*FR[0][1];
rb = b[0]*FR[1][2] + b[2]*FR[1][0];
t = Math::Abs( T[0]*R[2][1] - T[2]*R[0][1] );
if( t > ra + rb ) return false;
//L = A1 x B2
ra = a[0]*FR[2][2] + a[2]*FR[0][2];
rb = b[0]*FR[1][1] + b[1]*FR[1][0];
t = Math::Abs( T[0]*R[2][2] - T[2]*R[0][2] );
if( t > ra + rb ) return false;
//L = A2 x B0
ra = a[0]*FR[1][0] + a[1]*FR[0][0];
rb = b[1]*FR[2][2] + b[2]*FR[2][1];
t = Math::Abs( T[1]*R[0][0] - T[0]*R[1][0] );
if( t > ra + rb ) return false;
//L = A2 x B1
ra = a[0]*FR[1][1] + a[1]*FR[0][1];
rb = b[0]*FR[2][2] + b[2]*FR[2][0];
t = Math::Abs( T[1]*R[0][1] - T[0]*R[1][1] );
if( t > ra + rb ) return false;
//L = A2 x B2
ra = a[0]*FR[1][2] + a[1]*FR[0][2];
rb = b[0]*FR[2][1] + b[1]*FR[2][0];
t = Math::Abs( T[1]*R[0][2] - T[0]*R[1][2] );
if( t > ra + rb ) return false;
// Phew! No separating axis found, no overlap!
return true;
}
//------------------------------------------------------------------------
bool OrientedBox::intersects( const OrientedBox& obb ) const
{
//translation, in parent frame (note: A = this, B = obb)
Vector3 v = obb.center - center;
//translation, in A's frame
Vector3 T( v.dotProduct( rot.GetColumn(0)),
v.dotProduct( rot.GetColumn(1)),
v.dotProduct( rot.GetColumn(2)) );
//B's basis with respect to A's local frame
Real R[3][3];
Real FR[3][3];
Real ra, rb, t;
long i, k;
//calculate rotation matrix from "obb" to "this" - palso recomputes the fabs matrix
for( i=0 ; i<3 ; i++ )
{
for( k=0 ; k<3 ; k++ )
{
R[i][k] = rot.GetColumn(i).dotProduct(obb.rot.GetColumn(k) );
// fabs and shift borrowed from RAPID
FR[i][k] = 1e-6f + Math::Abs(R[i][k]);
}
}
// Separating axis theorem: test of all 15 potential separating axes
// These axes are always parallel to each OBB edges or its normal plane
const Vector3 &a = extents,
&b = obb.extents;
// First stage: each obb's axis!
//A's basis vectors
for( i=0 ; i<3 ; i++ )
{
ra = a[i];
rb = b.x*FR[i][0] + b.y*FR[i][1] + b.z*FR[i][2];
t = Math::Abs( T[i] );
if( t > ra + rb ) return false;
}
//B's basis vectors
for( k=0 ; k<3 ; k++ )
{
ra = a.x*FR[0][k] + a.y*FR[1][k] + a.z*FR[2][k];
rb = b[k];
t = Math::Abs( T[0]*R[0][k] + T[1]*R[1][k] + T[2]*R[2][k] );
if( t > ra + rb ) return false;
}
// Second stage: 9 cross products
//L = A0 x B0
ra = a[1]*FR[2][0] + a[2]*FR[1][0];
rb = b[1]*FR[0][2] + b[2]*FR[0][1];
t = Math::Abs( T[2]*R[1][0] - T[1]*R[2][0] );
if( t > ra + rb ) return false;
//L = A0 x B1
ra = a[1]*FR[2][1] + a[2]*FR[1][1];
rb = b[0]*FR[0][2] + b[2]*FR[0][0];
t = Math::Abs( T[2]*R[1][1] - T[1]*R[2][1] );
if( t > ra + rb ) return false;
//L = A0 x B2
ra = a[1]*FR[2][2] + a[2]*FR[1][2];
rb = b[0]*FR[0][1] + b[1]*FR[0][0];
t = Math::Abs( T[2]*R[1][2] - T[1]*R[2][2] );
if( t > ra + rb ) return false;
//L = A1 x B0
ra = a[0]*FR[2][0] + a[2]*FR[0][0];
rb = b[1]*FR[1][2] + b[2]*FR[1][1];
t = Math::Abs( T[0]*R[2][0] - T[2]*R[0][0] );
if( t > ra + rb ) return false;
//L = A1 x B1
ra = a[0]*FR[2][1] + a[2]*FR[0][1];
rb = b[0]*FR[1][2] + b[2]*FR[1][0];
t = Math::Abs( T[0]*R[2][1] - T[2]*R[0][1] );
if( t > ra + rb ) return false;
//L = A1 x B2
ra = a[0]*FR[2][2] + a[2]*FR[0][2];
rb = b[0]*FR[1][1] + b[1]*FR[1][0];
t = Math::Abs( T[0]*R[2][2] - T[2]*R[0][2] );
if( t > ra + rb ) return false;
//L = A2 x B0
ra = a[0]*FR[1][0] + a[1]*FR[0][0];
rb = b[1]*FR[2][2] + b[2]*FR[2][1];
t = Math::Abs( T[1]*R[0][0] - T[0]*R[1][0] );
if( t > ra + rb ) return false;
//L = A2 x B1
ra = a[0]*FR[1][1] + a[1]*FR[0][1];
rb = b[0]*FR[2][2] + b[2]*FR[2][0];
t = Math::Abs( T[1]*R[0][1] - T[0]*R[1][1] );
if( t > ra + rb ) return false;
//L = A2 x B2
ra = a[0]*FR[1][2] + a[1]*FR[0][2];
rb = b[0]*FR[2][1] + b[1]*FR[2][0];
t = Math::Abs( T[1]*R[0][2] - T[0]*R[1][2] );
if( t > ra + rb ) return false;
// Phew! No separating axis found, no overlap!
return true;
}
//------------------------------------------------------------------------
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -