OBB(Oriented Bounding Box)有向包围盒。具体概念和算法网上很多,这里就不赘述了,直接上代码。
先看测试演示Demo: OBB相交检测测试演示,方便实际尝试,界面效果如下图:
上图所用的主要源码在下面给出(代码中用到的Vecter3相关的源码很常见,这里就不给出了)。
C++源码:
template <typename NumberType>
NumberType OBB<NumberType>::AbsR[3][3]{0.0f};
template <typename NumberType>
NumberType OBB<NumberType>::R[3][3]{0.0f};
template <typename NumberType>
OBB<NumberType>::OBB() noexcept
:
version(-1),
radius(0.0f),
m_ts{0.0f},
extents{0.0}
{
}
template <typename NumberType>
void OBB<NumberType>::update()
{
version++;
for (auto i = 0; i < 3; ++i) axes[i].normalize();
auto et = extent;
radius = et.getLength();
//et.toArray3(extents.data());
et.toArray3(extents);
}
template <typename NumberType>
bool OBB<NumberType>::containsV(const Vec3<NumberType>& pv) noexcept
{
m_pv.subVecsTo(pv, center);
auto v0 = m_pv;
using namespace std;
auto& et = extent;
return abs(v0.dot(axes[0])) <= et.x && abs(v0.dot(axes[1])) <= et.y && abs(v0.dot(axes[2])) <= et.z;
}
template <typename NumberType>
bool OBB<NumberType>::intersect(const OBB& obb, NumberType epsilon)
{
auto& a = *this;
auto& b = obb;
using namespace std;
// 计算距离向量tv
m_pv.subVecsTo(b.center, a.center);
auto& tv = m_pv;
if (tv.getLength() - (a.radius + b.radius) > epsilon)
{
return false;
}
auto Avs = OBB<NumberType>::AbsR;
auto Rvs = OBB<NumberType>::R;
// 计算旋转矩阵R
for (auto i = 0; i < 3; ++i)
{
for (auto j &