140 lines
No EOL
3.3 KiB
C++
140 lines
No EOL
3.3 KiB
C++
#include "StdAfx.h"
|
|
#include "EtCollisionMng.h"
|
|
#include "EtFindCollision.h"
|
|
#include "StringUtil.h"
|
|
|
|
std::map< long, CEtCollisionMng::SKdTreeData > CEtCollisionMng::s_mapKdTree;
|
|
CSyncLock CEtCollisionMng::s_Lock;
|
|
|
|
CEtCollisionMng::CEtCollisionMng( CMultiRoom *pRoom )
|
|
: CMultiSingleton<CEtCollisionMng, MAX_SESSION_COUNT>( pRoom )
|
|
{
|
|
m_pCurKdTree = NULL;
|
|
}
|
|
|
|
CEtCollisionMng::~CEtCollisionMng(void)
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void CEtCollisionMng::Clear()
|
|
{
|
|
ScopeLock<CSyncLock> Lock(s_Lock);
|
|
|
|
std::map< long, SKdTreeData >::iterator it = s_mapKdTree.begin();
|
|
|
|
while( it != s_mapKdTree.end() )
|
|
{
|
|
if( it->second.pKdTree == m_pCurKdTree )
|
|
{
|
|
it->second.nRefCount--;
|
|
if( it->second.nRefCount <= 0 )
|
|
{
|
|
delete m_pCurKdTree;
|
|
m_pCurKdTree = NULL;
|
|
s_mapKdTree.erase( it );
|
|
}
|
|
break;
|
|
}
|
|
it++;
|
|
}
|
|
}
|
|
|
|
bool CEtCollisionMng::FindCollision( std::vector< SCollisionPrimitive * > &vecPrimitive, SAABox &BoundingBox, EtVector3 &vMove, DNVector(SCollisionResponse) &vecResponse, bool bCalcContactTime )
|
|
{
|
|
if( m_pCurKdTree == NULL )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
int i;
|
|
bool bCollision;
|
|
static std::vector< SKdTreeCollisionPrimitive * > vecResult[MAX_SESSION_COUNT];
|
|
SCollisionResponse Response;
|
|
|
|
bCollision = false;
|
|
vecResult[GetRoom()->GetRoomID()].clear();
|
|
m_pCurKdTree->Pick( BoundingBox, vecResult[GetRoom()->GetRoomID()] );
|
|
if( !vecResult[GetRoom()->GetRoomID()].empty() )
|
|
{
|
|
std::vector< SKdTreeCollisionPrimitive * >::iterator it;
|
|
it = vecResult[GetRoom()->GetRoomID()].begin();
|
|
Response.vMove = vMove;
|
|
for( i = 0; i < ( int )vecPrimitive.size(); i++ )
|
|
{
|
|
for( ; it != vecResult[GetRoom()->GetRoomID()].end(); it++ )
|
|
{
|
|
if( CEtCollisionFinder::GetInstance().FindCollision( *vecPrimitive[ i ], *( ( *it )->pPrimitive), Response, bCalcContactTime ) )
|
|
{
|
|
Response.pCollisionPrimitive = ( *it )->pPrimitive;
|
|
vecResponse.push_back( Response );
|
|
if( Response.vExtraNormal.x != FLT_MAX )
|
|
{
|
|
Response.vNormal = Response.vExtraNormal;
|
|
vecResponse.push_back( Response );
|
|
}
|
|
bCollision = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return bCollision;
|
|
}
|
|
|
|
void CEtCollisionMng::Load( CStream *pStream )
|
|
{
|
|
if( m_pCurKdTree )
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
s_Lock.Lock();
|
|
|
|
std::string szTemp = pStream->GetName();
|
|
ToLowerA( szTemp );
|
|
long lHashCode = GetHashCode( szTemp.c_str() );
|
|
std::map< long, SKdTreeData >::iterator it = s_mapKdTree.find( lHashCode );
|
|
if( it != s_mapKdTree.end() )
|
|
{
|
|
it->second.nRefCount++;
|
|
m_pCurKdTree = it->second.pKdTree;
|
|
s_Lock.UnLock();
|
|
return;
|
|
}
|
|
|
|
SKdTreeData KdTreeData;
|
|
KdTreeData.pKdTree = new TKdTree< SKdTreeCollisionPrimitive >;
|
|
KdTreeData.nRefCount = 1;
|
|
s_mapKdTree.insert( std::make_pair( lHashCode, KdTreeData ) );
|
|
|
|
s_Lock.UnLock();
|
|
|
|
m_pCurKdTree = KdTreeData.pKdTree;
|
|
m_pCurKdTree->LoadTree( pStream );
|
|
}
|
|
|
|
void CEtCollisionMng::PreLoad( CStream *pStream )
|
|
{
|
|
s_Lock.Lock();
|
|
|
|
std::string szTemp = pStream->GetName();
|
|
ToLowerA( szTemp );
|
|
long lHashCode = GetHashCode( szTemp.c_str() );
|
|
std::map< long, SKdTreeData >::iterator it = s_mapKdTree.find( lHashCode );
|
|
if( it != s_mapKdTree.end() )
|
|
{
|
|
it->second.nRefCount++;
|
|
s_Lock.UnLock();
|
|
return;
|
|
}
|
|
|
|
SKdTreeData KdTreeData;
|
|
KdTreeData.pKdTree = new TKdTree< SKdTreeCollisionPrimitive >;
|
|
KdTreeData.nRefCount = 1;
|
|
s_mapKdTree.insert( std::make_pair( lHashCode, KdTreeData ) );
|
|
|
|
s_Lock.UnLock();
|
|
|
|
KdTreeData.pKdTree->LoadTree( pStream );
|
|
} |