455 lines
12 KiB
C++
455 lines
12 KiB
C++
#ifndef __K3DBOUND_INCLUDE__
|
|
#define __K3DBOUND_INCLUDE__
|
|
|
|
#include "K3DTypes.h"
|
|
#include "K3DPCCP.h"
|
|
|
|
|
|
class KViewportObject;
|
|
class K3DBoundRot {
|
|
protected:
|
|
K3DMatrix m_matrix;
|
|
mutable bool m_transformchanged;
|
|
|
|
public:
|
|
K3DBoundRot() { K3DMatrixIdentity(m_matrix); m_transformchanged = false; }
|
|
K3DBoundRot(const K3DMatrix &mat) { m_matrix = mat; m_transformchanged = true; }
|
|
virtual ~K3DBoundRot() {}
|
|
|
|
void SetTransform( const K3DMatrix &mat )
|
|
{
|
|
m_matrix = mat;
|
|
m_transformchanged = true;
|
|
}
|
|
void AddTransform( const K3DMatrix &mat )
|
|
{
|
|
K3DMatrixMultiply(m_matrix, m_matrix, mat);
|
|
m_transformchanged = true;
|
|
}
|
|
const K3DMatrix& GetTransform() const { return m_matrix; }
|
|
|
|
virtual void Render( KViewportObject *viewport ) {};
|
|
virtual K3DBoundRot* Clone() = 0;
|
|
virtual bool CheckCollision(const K3DVertex &v1, const K3DVertex &v2) const = 0;
|
|
virtual bool CheckCollision ( const K3DBoundRot *cube ) const = 0;
|
|
};
|
|
|
|
|
|
class KWireUtilPrimitive;
|
|
class K3DBoundRotCube : public K3DBoundRot
|
|
{
|
|
public:
|
|
K3DBoundRotCube()
|
|
: K3DBoundRot(), m_pr( NULL ), m_prPlan( NULL ),m_WireColor( KColor( 0, 255, 0, 255 ) ), m_bWireComplex( false ), m_bColorGradation(false)
|
|
{ ClearCube(); }
|
|
|
|
K3DBoundRotCube( const K3DBoundRotCube &cube )
|
|
: K3DBoundRot(cube.m_matrix), m_pr( NULL ), m_prPlan( NULL ),m_WireColor( KColor( 0, 255, 0, 255 ) ), m_bWireComplex( false ), m_bColorGradation(false)
|
|
{ ClearCube(); memcpy( m_vtx, cube.m_vtx, sizeof(m_vtx) ); }
|
|
|
|
K3DBoundRotCube( const K3DBoundRotCube* cube )
|
|
: K3DBoundRot(cube->m_matrix), m_pr( NULL ), m_prPlan( NULL ),m_WireColor( KColor( 0, 255, 0, 255 ) ), m_bWireComplex( false ), m_bColorGradation(false)
|
|
{ ClearCube(); memcpy( m_vtx, cube->m_vtx, sizeof(m_vtx) ); }
|
|
|
|
K3DBoundRotCube( float minx, float maxx, float miny, float maxy, float minz, float maxz )
|
|
: K3DBoundRot(), m_pr( NULL ), m_prPlan( NULL ),m_WireColor( KColor( 0, 255, 0, 255 ) ), m_bWireComplex( false ), m_bColorGradation(false)
|
|
{
|
|
for( int n = 0; n < 8; ++n )
|
|
{
|
|
m_transvtx[ n ] = m_vtx[ n ] = KPCCP::get_cube_vertex(
|
|
n,
|
|
minx, maxx,
|
|
miny, maxy,
|
|
minz, maxz );
|
|
}
|
|
}
|
|
|
|
~K3DBoundRotCube();
|
|
|
|
const K3DBoundRotCube& operator=( const K3DBoundRotCube& r );
|
|
|
|
const KColor& GetWireColor() const { return m_WireColor; }
|
|
void SetWireColor( const KColor& rColor ) { m_WireColor = rColor; }
|
|
|
|
bool GetWireDrawMode() const { return m_bWireComplex; }
|
|
void SetWireDrawMode( bool bComplex ) { m_bWireComplex = bComplex; }
|
|
|
|
void SetColorGradation( bool bColorGradation ) { m_bColorGradation = bColorGradation; }
|
|
|
|
void SetCube( const K3DVertex *vtxs )
|
|
{
|
|
memcpy( m_vtx, vtxs, sizeof(m_vtx) );
|
|
m_transformchanged = true;
|
|
}
|
|
void ClearCube()
|
|
{
|
|
memset( m_transvtx, 0, sizeof(m_transvtx) ); memset( m_vtx, 0, sizeof(m_vtx) );
|
|
}
|
|
bool CheckCollision ( const K3DBoundRot *cube ) const
|
|
{
|
|
K3DBoundRotCube* tcube = (K3DBoundRotCube*)cube;
|
|
updateTransform();
|
|
tcube->updateTransform();
|
|
|
|
return KPCCP::rotcube_collide_rotcube( m_transvtx, tcube->m_transvtx );
|
|
}
|
|
|
|
virtual bool CheckCollision(const K3DVertex &v1, const K3DVertex &v2) const
|
|
{
|
|
K3DVertex v[2];
|
|
v[0] = v1;
|
|
v[1] = v2;
|
|
updateTransform();
|
|
return KPCCP::edge_collide_nonuniformcube( v, m_transvtx );
|
|
}
|
|
|
|
float GetWidth() const
|
|
{
|
|
updateTransform();
|
|
float minx, maxx;
|
|
minx = maxx = m_transvtx[0].x;
|
|
for ( int i=1 ; i<8 ; i++ ) {
|
|
if ( minx > m_transvtx[i].x ) minx = m_transvtx[i].x;
|
|
if ( maxx < m_transvtx[i].x ) maxx = m_transvtx[i].x;
|
|
}
|
|
|
|
return maxx - minx;
|
|
}
|
|
float GetLength() const
|
|
{
|
|
updateTransform();
|
|
float miny, maxy;
|
|
miny = maxy = m_transvtx[0].y;
|
|
for ( int i=1 ; i<8 ; i++ ) {
|
|
if ( miny > m_transvtx[i].y ) miny = m_transvtx[i].y;
|
|
if ( maxy < m_transvtx[i].y ) maxy = m_transvtx[i].y;
|
|
}
|
|
|
|
return maxy - miny;
|
|
}
|
|
float GetHeight() const
|
|
{
|
|
updateTransform();
|
|
float minz, maxz;
|
|
minz = maxz = m_transvtx[0].z;
|
|
for ( int i=1 ; i<8 ; i++ ) {
|
|
if ( minz > m_transvtx[i].z ) minz = m_transvtx[i].z;
|
|
if ( maxz < m_transvtx[i].z ) maxz = m_transvtx[i].z;
|
|
}
|
|
|
|
return maxz - minz;
|
|
}
|
|
K3DVertex GetMinVertex() const
|
|
{
|
|
updateTransform();
|
|
float minx = m_transvtx[0].x;
|
|
float miny = m_transvtx[0].y;
|
|
float minz = m_transvtx[0].z;
|
|
|
|
for ( int i=1 ; i<8 ; i++ ) {
|
|
if ( minx > m_transvtx[i].x ) minx = m_transvtx[i].x;
|
|
if ( miny > m_transvtx[i].y ) miny = m_transvtx[i].y;
|
|
if ( minz > m_transvtx[i].z ) minz = m_transvtx[i].z;
|
|
}
|
|
|
|
return K3DVertex( minx, miny, minz );
|
|
}
|
|
K3DVertex GetMaxVertex() const
|
|
{
|
|
updateTransform();
|
|
float maxx = m_transvtx[0].x;
|
|
float maxy = m_transvtx[0].y;
|
|
float maxz = m_transvtx[0].z;
|
|
|
|
for ( int i=1 ; i<8 ; i++ ) {
|
|
if ( maxx < m_transvtx[i].x ) maxx = m_transvtx[i].x;
|
|
if ( maxy < m_transvtx[i].y ) maxy = m_transvtx[i].y;
|
|
if ( maxz < m_transvtx[i].z ) maxz = m_transvtx[i].z;
|
|
}
|
|
|
|
return K3DVertex( maxx, maxy, maxz );
|
|
}
|
|
|
|
K3DVertex GetCenterPos()
|
|
{
|
|
K3DVertex pos;
|
|
K3DMatrixGetPosVector( pos, m_matrix );
|
|
return pos;
|
|
}
|
|
|
|
const K3DVertex* GetVertices() const
|
|
{
|
|
updateTransform();
|
|
return m_transvtx;
|
|
}
|
|
|
|
const K3DVertex* GetOriginVertices() const
|
|
{
|
|
return m_vtx;
|
|
}
|
|
|
|
virtual K3DBoundRot* Clone()
|
|
{
|
|
K3DBoundRot *clone= new K3DBoundRotCube(this);
|
|
return clone;
|
|
}
|
|
|
|
void AddCube( const K3DBoundRotCube &cube );
|
|
virtual void Render( KViewportObject *viewport );
|
|
|
|
void CreatePlanPrimitive();
|
|
class KPlanUtilPrimitive* GetPlanPrimitive() { return m_prPlan; }
|
|
|
|
/// 2012.06.26 충돌 체크에 쓰인 블럭 라인은 구한다 - prodongi
|
|
void getBlockLine(int* blockLine)
|
|
{
|
|
updateTransform();
|
|
/// 시계방향
|
|
|
|
/// 긴 라인이 0과 1이 되게 한다
|
|
K3DVertex v10 = m_transvtx[1] - m_transvtx[0];
|
|
K3DVertex v30 = m_transvtx[3] - m_transvtx[0];
|
|
|
|
float len10 = v10.SquareMagnitude();
|
|
float len30 = v30.SquareMagnitude();
|
|
|
|
if (len10 < len30)
|
|
{
|
|
blockLine[0] = (int)m_transvtx[0].x; blockLine[1] = (int)m_transvtx[0].y; /// 0
|
|
blockLine[2] = (int)m_transvtx[3].x; blockLine[3] = (int)m_transvtx[3].y; /// 1
|
|
}
|
|
else
|
|
{
|
|
blockLine[0] = (int)m_transvtx[0].x; blockLine[1] = (int)m_transvtx[0].y; /// 0
|
|
blockLine[2] = (int)m_transvtx[1].x; blockLine[3] = (int)m_transvtx[1].y; /// 1
|
|
}
|
|
/*
|
|
if (len10 < len30)
|
|
{
|
|
blockLine[0] = (int)m_transvtx[0].x; blockLine[1] = (int)m_transvtx[0].y; /// 0
|
|
blockLine[2] = (int)m_transvtx[3].x; blockLine[3] = (int)m_transvtx[3].y; /// 1
|
|
blockLine[4] = (int)m_transvtx[2].x; blockLine[5] = (int)m_transvtx[2].y; /// 2
|
|
blockLine[6] = (int)m_transvtx[1].x; blockLine[7] = (int)m_transvtx[1].y; /// 3
|
|
blockLine[8] = (int)m_transvtx[0].x; blockLine[9] = (int)m_transvtx[0].y; /// 4
|
|
}
|
|
else
|
|
{
|
|
blockLine[0] = (int)m_transvtx[3].x; blockLine[1] = (int)m_transvtx[3].y; /// 0
|
|
blockLine[2] = (int)m_transvtx[2].x; blockLine[3] = (int)m_transvtx[2].y; /// 1
|
|
blockLine[4] = (int)m_transvtx[1].x; blockLine[5] = (int)m_transvtx[1].y; /// 2
|
|
blockLine[6] = (int)m_transvtx[0].x; blockLine[7] = (int)m_transvtx[0].y; /// 3
|
|
blockLine[8] = (int)m_transvtx[3].x; blockLine[9] = (int)m_transvtx[3].y; /// 4
|
|
}
|
|
*/
|
|
}
|
|
|
|
private:
|
|
void updateTransform() const
|
|
{
|
|
if ( m_transformchanged )
|
|
{
|
|
//K3DMatrix res;
|
|
//Multiply(res, m_matrix, m_parentMatrix);
|
|
for ( int i=0 ; i<8 ; i++ ) {
|
|
K3DVectorTransform( m_transvtx[i], m_vtx[i], m_matrix );
|
|
}
|
|
m_transformchanged = false;
|
|
}
|
|
}
|
|
|
|
void AddLines( const int* pLineIndices, int nCount );
|
|
|
|
private:
|
|
K3DVertex m_vtx[8];
|
|
mutable K3DVertex m_transvtx[8];
|
|
|
|
KWireUtilPrimitive* m_pr;
|
|
KPlanUtilPrimitive* m_prPlan;
|
|
bool m_bColorGradation;
|
|
KColor m_WireColor;
|
|
bool m_bWireComplex;
|
|
};
|
|
|
|
class K3DBoundRotRect : public K3DBoundRot
|
|
{
|
|
public:
|
|
K3DBoundRotRect() : K3DBoundRot()
|
|
{ memset( m_transvtx, 0, sizeof(m_transvtx) ); memset( m_vtx, 0, sizeof(m_vtx) ); }
|
|
K3DBoundRotRect( const K3DBoundRotRect &rect) : K3DBoundRot(rect.m_matrix)
|
|
{ memcpy( m_vtx, rect.m_vtx, sizeof(m_vtx) ); }
|
|
K3DBoundRotRect( const K3DBoundRotRect* rect) : K3DBoundRot(rect->m_matrix)
|
|
{ memcpy( m_vtx, rect->m_vtx, sizeof(m_vtx) ); }
|
|
|
|
void SetRect( K3DVertex *vtxs )
|
|
{
|
|
memcpy( m_vtx, vtxs, sizeof(m_vtx) );
|
|
m_transformchanged = true;
|
|
}
|
|
bool CheckCollision ( const K3DBoundRot *rect ) const
|
|
{
|
|
K3DBoundRotRect* trect = (K3DBoundRotRect*)rect;
|
|
updateTransform();
|
|
trect->updateTransform();
|
|
|
|
return KPCCP::rect_collide_rect( m_transvtx, trect->m_transvtx );
|
|
}
|
|
virtual bool CheckCollision(const K3DVertex &v1, const K3DVertex &v2) const
|
|
{
|
|
updateTransform();
|
|
return KPCCP::quad_collide_edge( m_transvtx[0], m_transvtx[1],
|
|
m_transvtx[2], m_transvtx[3],
|
|
v1, v2 );
|
|
}
|
|
bool GetTopHeight( float &height ) const
|
|
{
|
|
updateTransform();
|
|
float y = m_transvtx[0].y;
|
|
for ( int i=1 ; i<4 ; i++ )
|
|
if ( y < m_transvtx[i].y ) y = m_transvtx[i].y;
|
|
height = y;
|
|
return true;
|
|
}
|
|
const K3DVertex* GetVertices() {
|
|
updateTransform();
|
|
return m_transvtx;
|
|
}
|
|
|
|
virtual K3DBoundRot* Clone()
|
|
{
|
|
K3DBoundRot *clone= new K3DBoundRotRect(this);
|
|
//clone->SetParentTransform(GetParentTransform());
|
|
return clone;
|
|
}
|
|
private:
|
|
void updateTransform() const
|
|
{
|
|
if ( m_transformchanged )
|
|
{
|
|
for ( int i=0 ; i<4 ; i++ )
|
|
K3DVectorTransform( m_transvtx[i], m_vtx[i], m_matrix );
|
|
m_transformchanged = false;
|
|
}
|
|
}
|
|
|
|
private:
|
|
K3DMatrix m_matrix;
|
|
K3DVertex m_vtx[4];
|
|
mutable K3DVertex m_transvtx[4];
|
|
};
|
|
|
|
|
|
/// - SPHERE - //////////////////////////////////////////
|
|
class K3DBoundSphere
|
|
{
|
|
public:
|
|
K3DBoundSphere()
|
|
{
|
|
m_transrad = m_radius = .0f;
|
|
K3DMatrixIdentity(m_matrix);
|
|
m_needTransform = false;
|
|
}
|
|
K3DBoundSphere( const K3DBoundSphere &sphere )
|
|
{
|
|
m_radius = sphere.m_radius;
|
|
m_position = sphere.m_position;
|
|
m_matrix = sphere.m_matrix;
|
|
m_needTransform = true;
|
|
}
|
|
|
|
void SetPosition(const K3DVertex pos) { m_position = pos; m_needTransform = true; }
|
|
void SetRadius(float radius) { m_radius = radius; m_needTransform = true; }
|
|
|
|
void AddSphere( const K3DBoundSphere &sphere );
|
|
|
|
const K3DVertex &GetPosition() const { updateTransform(); return m_transpos; }
|
|
float GetRadius() const { updateTransform(); return m_transrad; }
|
|
|
|
public:
|
|
bool CheckCollision(K3DBoundSphere *sphere) const
|
|
{
|
|
updateTransform();
|
|
sphere->updateTransform();
|
|
if ( ( (m_transpos.x - sphere->m_transpos.x) * (m_transpos.x - sphere->m_transpos.x)
|
|
+ (m_transpos.y - sphere->m_transpos.y) * (m_transpos.y - sphere->m_transpos.y)
|
|
+ (m_transpos.z - sphere->m_transpos.z) * (m_transpos.z - sphere->m_transpos.z))
|
|
<= ((m_transrad + sphere->m_transrad) * (m_transrad + sphere->m_transrad)) )
|
|
return true;
|
|
}
|
|
bool CheckCollision(const K3DVertex &v1, const K3DVertex &v2, const K3DVertex &v3) const;
|
|
bool CheckCollision(const K3DVertex &v1, const K3DVertex &v2) const;
|
|
void SetTransform( const K3DMatrix &mat )
|
|
{
|
|
m_matrix = mat;
|
|
m_needTransform = true;
|
|
}
|
|
|
|
bool operator == ( const K3DBoundSphere &sp ) const {
|
|
return (m_position.x == sp.m_position.x && m_position.y == sp.m_position.y &&
|
|
m_position.z == sp.m_position.z && m_radius == sp.m_radius);
|
|
}
|
|
|
|
private:
|
|
void updateTransform() const
|
|
{
|
|
if ( m_needTransform == true )
|
|
{
|
|
K3DVectorTransform( m_transpos, m_position, m_matrix );
|
|
K3DVector res(m_position);
|
|
res += K3DVector(m_radius,0,0);
|
|
K3DVectorTransform( res, res, m_matrix );
|
|
res = m_transpos - res;
|
|
m_transrad = K3DVectorLength(res);
|
|
m_needTransform = false;
|
|
}
|
|
}
|
|
private:
|
|
K3DVertex m_position;
|
|
float m_radius;
|
|
K3DMatrix m_matrix;
|
|
mutable K3DVertex m_transpos;
|
|
mutable float m_transrad;
|
|
mutable bool m_needTransform;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
/// 오클루젼 컬링을 위한 바운드 박스
|
|
class K3DBoundOcclusion
|
|
{
|
|
private:
|
|
K3DVertex m_vtx[8];
|
|
bool m_bCheked;
|
|
public:
|
|
K3DBoundOcclusion() : m_bCheked( false )
|
|
{
|
|
memset( m_vtx, 0, sizeof(m_vtx) );
|
|
}
|
|
~K3DBoundOcclusion()
|
|
{
|
|
}
|
|
|
|
K3DVertex* GetVertices()
|
|
{
|
|
return m_vtx;
|
|
}
|
|
|
|
void SetVertices( const K3DVertex* pVertices )
|
|
{
|
|
*m_vtx[0] = *pVertices[0];
|
|
*m_vtx[1] = *pVertices[5];
|
|
*m_vtx[2] = *pVertices[3];
|
|
*m_vtx[3] = *pVertices[6];
|
|
|
|
*m_vtx[4] = *pVertices[1];
|
|
*m_vtx[5] = *pVertices[4];
|
|
*m_vtx[6] = *pVertices[2];
|
|
*m_vtx[7] = *pVertices[7];
|
|
}
|
|
|
|
bool IsChecked() { return m_bCheked; }
|
|
void SetCheck( bool bCheck ) { m_bCheked = bCheck; }
|
|
};
|
|
|
|
|
|
/// utilities
|
|
bool K3DBoundSetCube( K3DBoundRotCube *cube, K3DVector *vertices, int nCount );
|
|
#endif |