231 lines
5.5 KiB
C++
231 lines
5.5 KiB
C++
/*
|
|
Copyright (c) 2012 Advanced Micro Devices, Inc.
|
|
|
|
This software is provided 'as-is', without any express or implied warranty.
|
|
In no event will the authors be held liable for any damages arising from the use of this software.
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it freely,
|
|
subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
|
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
*/
|
|
//Originally written by Takahiro Harada
|
|
|
|
#ifndef AABB_H
|
|
#define AABB_H
|
|
|
|
#include "Stubs/AdlMath.h"
|
|
#include "Stubs/AdlQuaternion.h"
|
|
|
|
enum AdlCollisionShapeTypes
|
|
{
|
|
ADL_SHAPE_SPHERE=2,
|
|
ADL_SHAPE_HEIGHT_FIELD,
|
|
SHAPE_CONVEX_HEIGHT_FIELD,
|
|
};
|
|
|
|
_MEM_CLASSALIGN16
|
|
struct Aabb
|
|
{
|
|
public:
|
|
_MEM_ALIGNED_ALLOCATOR16;
|
|
|
|
__inline
|
|
void setEmpty();
|
|
__inline
|
|
void includeVolume( const Aabb& aabb );
|
|
__inline
|
|
void includePoint( const float4& p );
|
|
__inline
|
|
bool overlaps( const float4& p ) const;
|
|
__inline
|
|
bool overlaps( const Aabb& aabb ) const;
|
|
__inline
|
|
float4 center() const;
|
|
__inline
|
|
int getMajorAxis() const;
|
|
__inline
|
|
float4 getExtent() const;
|
|
__inline
|
|
void expandBy( const float4& r );
|
|
|
|
__inline
|
|
static bool overlaps( const Aabb& a, const Aabb& b );
|
|
|
|
__inline
|
|
bool intersect(const float4* from, const float4* to, const float4* invRay) const;
|
|
|
|
__inline
|
|
void transform(const float4& translation, const Quaternion& quat);
|
|
|
|
__inline
|
|
void transform(const float4& translation, const Matrix3x3& rot);
|
|
|
|
public:
|
|
float4 m_max;
|
|
float4 m_min;
|
|
};
|
|
|
|
void Aabb::setEmpty()
|
|
{
|
|
m_max = make_float4( -FLT_MAX );
|
|
m_min = make_float4( FLT_MAX );
|
|
}
|
|
|
|
void Aabb::includeVolume(const Aabb& aabb)
|
|
{
|
|
m_max.x = max2( m_max.x, aabb.m_max.x );
|
|
m_min.x = min2( m_min.x, aabb.m_min.x );
|
|
|
|
m_max.y = max2( m_max.y, aabb.m_max.y );
|
|
m_min.y = min2( m_min.y, aabb.m_min.y );
|
|
|
|
m_max.z = max2( m_max.z, aabb.m_max.z );
|
|
m_min.z = min2( m_min.z, aabb.m_min.z );
|
|
}
|
|
|
|
void Aabb::includePoint( const float4& p )
|
|
{
|
|
m_max.x = max2( m_max.x, p.x );
|
|
m_min.x = min2( m_min.x, p.x );
|
|
|
|
m_max.y = max2( m_max.y, p.y );
|
|
m_min.y = min2( m_min.y, p.y );
|
|
|
|
m_max.z = max2( m_max.z, p.z );
|
|
m_min.z = min2( m_min.z, p.z );
|
|
}
|
|
|
|
bool Aabb::overlaps( const float4& p ) const
|
|
{
|
|
float4 dx = m_max-p;
|
|
float4 dm = p-m_min;
|
|
|
|
return (dx.x >= 0 && dx.y >= 0 && dx.z >= 0)
|
|
&& (dm.x >= 0 && dm.y >= 0 && dm.z >= 0);
|
|
}
|
|
|
|
bool Aabb::overlaps( const Aabb& in ) const
|
|
{
|
|
/*
|
|
if( m_max.x < in.m_min.x || m_min.x > in.m_max.x ) return false;
|
|
if( m_max.y < in.m_min.y || m_min.y > in.m_max.y ) return false;
|
|
if( m_max.z < in.m_min.z || m_min.z > in.m_max.z ) return false;
|
|
|
|
return true;
|
|
*/
|
|
return overlaps( *this, in );
|
|
}
|
|
|
|
bool Aabb::overlaps( const Aabb& a, const Aabb& b )
|
|
{
|
|
if( a.m_max.x < b.m_min.x || a.m_min.x > b.m_max.x ) return false;
|
|
if( a.m_max.y < b.m_min.y || a.m_min.y > b.m_max.y ) return false;
|
|
if( a.m_max.z < b.m_min.z || a.m_min.z > b.m_max.z ) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
float4 Aabb::center() const
|
|
{
|
|
return 0.5f*(m_max+m_min);
|
|
}
|
|
|
|
int Aabb::getMajorAxis() const
|
|
{
|
|
float4 extent = getExtent();
|
|
|
|
int majorAxis = 0;
|
|
if( extent.s[1] > extent.s[0] )
|
|
majorAxis = 1;
|
|
if( extent.s[2] > extent.s[majorAxis] )
|
|
majorAxis = 2;
|
|
|
|
return majorAxis;
|
|
}
|
|
|
|
float4 Aabb::getExtent() const
|
|
{
|
|
return m_max-m_min;
|
|
}
|
|
|
|
void Aabb::expandBy( const float4& r )
|
|
{
|
|
m_max += r;
|
|
m_min -= r;
|
|
}
|
|
|
|
bool Aabb::intersect(const float4* from, const float4* to, const float4* invRay) const
|
|
{
|
|
float4 dFar;
|
|
dFar = (m_max - *from);
|
|
dFar *= *invRay;
|
|
float4 dNear;
|
|
dNear = (m_min - *from);
|
|
dNear *= *invRay;
|
|
|
|
float4 tFar;
|
|
tFar = max2(dFar, dNear);
|
|
float4 tNear;
|
|
tNear = min2(dFar, dNear);
|
|
|
|
float farf[] = { tFar.x, tFar.y, tFar.z };
|
|
|
|
float nearf[] = { tNear.x, tNear.y, tNear.z };
|
|
|
|
float minFar = min2(farf[0], min2(farf[1], farf[2]));
|
|
float maxNear = max2(nearf[0], max2(nearf[1], nearf[2]));
|
|
|
|
minFar = min2(1.0f, minFar );
|
|
maxNear = max2(0.0f, maxNear);
|
|
|
|
return (minFar >= maxNear);
|
|
}
|
|
|
|
void Aabb::transform(const float4& translation, const Matrix3x3& m)
|
|
{
|
|
float4 c = center();
|
|
|
|
Aabb& ans = *this;
|
|
|
|
float4 e[] = { m.m_row[0]*m_min, m.m_row[1]*m_min, m.m_row[2]*m_min };
|
|
float4 f[] = { m.m_row[0]*m_max, m.m_row[1]*m_max, m.m_row[2]*m_max };
|
|
ans.m_max = ans.m_min = translation;
|
|
|
|
{ int j=0;
|
|
float4 mi = make_float4( min2( e[j].x, f[j].x ), min2( e[j].y, f[j].y ), min2( e[j].z, f[j].z ) );
|
|
float4 ma = make_float4( max2( e[j].x, f[j].x ), max2( e[j].y, f[j].y ), max2( e[j].z, f[j].z ) );
|
|
|
|
ans.m_min.x += mi.x+mi.y+mi.z;
|
|
ans.m_max.x += ma.x+ma.y+ma.z;
|
|
}
|
|
|
|
{ int j=1;
|
|
float4 mi = make_float4( min2( e[j].x, f[j].x ), min2( e[j].y, f[j].y ), min2( e[j].z, f[j].z ) );
|
|
float4 ma = make_float4( max2( e[j].x, f[j].x ), max2( e[j].y, f[j].y ), max2( e[j].z, f[j].z ) );
|
|
|
|
ans.m_min.y += mi.x+mi.y+mi.z;
|
|
ans.m_max.y += ma.x+ma.y+ma.z;
|
|
}
|
|
|
|
{ int j=2;
|
|
float4 mi = make_float4( min2( e[j].x, f[j].x ), min2( e[j].y, f[j].y ), min2( e[j].z, f[j].z ) );
|
|
float4 ma = make_float4( max2( e[j].x, f[j].x ), max2( e[j].y, f[j].y ), max2( e[j].z, f[j].z ) );
|
|
|
|
ans.m_min.z += mi.x+mi.y+mi.z;
|
|
ans.m_max.z += ma.x+ma.y+ma.z;
|
|
}
|
|
}
|
|
|
|
void Aabb::transform(const float4& translation, const Quaternion& quat)
|
|
{
|
|
Matrix3x3 m = qtGetRotationMatrix( quat );
|
|
|
|
transform( translation, m );
|
|
}
|
|
|
|
#endif
|
|
|