Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,775 @@
|
||||
#include "CharSphereTree.h"
|
||||
#include <cassert>
|
||||
|
||||
#include <Creature/Character/Character.h>
|
||||
#include <Network/Dispatch/GameClient/GameClientDispatch.h>
|
||||
|
||||
CCharSphereTree& CCharSphereTree::GetInstance()
|
||||
{
|
||||
static CCharSphereTree ms_this( SphereConst::MAX_SPHERE_NODE,
|
||||
SphereConst::DEFAULT_ROOT_SIZE,
|
||||
SphereConst::DEFAULT_LEAF_SIZE,
|
||||
SphereConst::DEFAULT_GRAVY );
|
||||
return ms_this;
|
||||
}
|
||||
|
||||
CCharSphereNode::CCharSphereNode() :
|
||||
m_dwCID(0),
|
||||
m_pCharacter(NULL),
|
||||
m_pParent(NULL),
|
||||
m_pChildren(NULL),
|
||||
m_pPrevSibling(NULL),
|
||||
m_pNextSibling(NULL),
|
||||
m_ppRecomuteFifo(NULL),
|
||||
m_ppIntegrateFifo(NULL),
|
||||
m_iChildCount(0),
|
||||
m_dwFlag(0),
|
||||
m_fBindingDistance2(0),
|
||||
m_pLink(NULL),
|
||||
m_pTree(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CCharSphereNode::CCharSphereNode( CCharSphereTree* pTree, const Position& Pos, float fRadius, void* pLink ) :
|
||||
CSphere(Pos, fRadius),
|
||||
m_dwCID(0),
|
||||
m_pCharacter(NULL),
|
||||
m_pParent(NULL),
|
||||
m_pChildren(NULL),
|
||||
m_pPrevSibling(NULL),
|
||||
m_pNextSibling(NULL),
|
||||
m_ppRecomuteFifo(NULL),
|
||||
m_ppIntegrateFifo(NULL),
|
||||
m_iChildCount(0),
|
||||
m_dwFlag(0),
|
||||
m_fBindingDistance2(0),
|
||||
m_pLink(pLink),
|
||||
m_pTree(pTree)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereNode::Init( CCharSphereTree* pTree, const Position& Pos, float fRadius, void* pLink )
|
||||
{
|
||||
m_pTree = pTree;
|
||||
m_Center = Pos;
|
||||
SetRadius( fRadius );
|
||||
m_pLink = pLink;
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereNode::AddChild( CCharSphereNode* pChild )
|
||||
{
|
||||
CCharSphereNode* pOldChild = m_pChildren;
|
||||
m_pChildren = pChild;
|
||||
|
||||
pChild->SetNextSibling( pOldChild );
|
||||
pChild->SetPrevSibling( NULL );
|
||||
pChild->SetParent( this );
|
||||
|
||||
if ( pOldChild )
|
||||
{
|
||||
pOldChild->SetPrevSibling( pChild );
|
||||
}
|
||||
|
||||
++m_iChildCount;
|
||||
|
||||
float fDist = Distance2( pChild );
|
||||
float fRadius = sqrtf( fDist ) + pChild->GetRadius();
|
||||
|
||||
assert( fRadius <= GetRadius() );
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereNode::DeleteChild( CCharSphereNode* pChild )
|
||||
{
|
||||
assert( m_iChildCount );
|
||||
assert( m_pChildren );
|
||||
|
||||
#ifdef _DEBUG
|
||||
// pChild <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD> üũ
|
||||
CCharSphereNode* pChildren = m_pChildren;
|
||||
bool bFound = false;
|
||||
|
||||
while ( pChildren )
|
||||
{
|
||||
if ( pChildren == pChild )
|
||||
{
|
||||
assert( !bFound );
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
pChildren = pChildren->GetNextSibling();
|
||||
}
|
||||
|
||||
assert( bFound );
|
||||
#endif
|
||||
|
||||
// Prev <20><> Next Sibling <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
CCharSphereNode* pPrev = pChild->GetPrevSibling();
|
||||
if ( pPrev )
|
||||
{
|
||||
CCharSphereNode* pNext = pChild->GetNextSibling();
|
||||
pPrev->SetNextSibling( pNext );
|
||||
if ( pNext ) pNext->SetPrevSibling( pPrev );
|
||||
}
|
||||
else
|
||||
{
|
||||
CCharSphereNode* pNext = pChild->GetNextSibling();
|
||||
m_pChildren = pNext;
|
||||
if ( m_pChildren ) m_pChildren->SetPrevSibling( NULL );
|
||||
}
|
||||
|
||||
--m_iChildCount;
|
||||
|
||||
if ( 0 == m_iChildCount && HasSphereNodeFlag( SNF_SUPERSPHERE ) )
|
||||
{
|
||||
m_pTree->DeleteSphere( this );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereNode::Unlink()
|
||||
{
|
||||
// Recompute & Integrate Fifo <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
if ( m_ppRecomuteFifo )
|
||||
{
|
||||
*m_ppRecomuteFifo = NULL;
|
||||
m_ppRecomuteFifo = NULL;
|
||||
}
|
||||
|
||||
if ( m_ppIntegrateFifo )
|
||||
{
|
||||
*m_ppIntegrateFifo = NULL;
|
||||
m_ppIntegrateFifo = NULL;
|
||||
}
|
||||
|
||||
if ( m_pParent )
|
||||
{
|
||||
m_pParent->DeleteChild( this );
|
||||
}
|
||||
|
||||
assert( !m_pChildren );
|
||||
|
||||
m_pParent = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereNode::NewPos( const Position& Pos )
|
||||
{
|
||||
// <20><><EFBFBD>ο<EFBFBD> <20><>ǥ <20><><EFBFBD><EFBFBD>
|
||||
m_Center = Pos;
|
||||
|
||||
// <20>θ<EFBFBD><CEB8><EFBFBD> <20>ְ<EFBFBD>, <20>籸<EFBFBD><E7B1B8><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD> <20><> <20>÷<EFBFBD><C3B7>װ<EFBFBD> <20><><EFBFBD>ٸ<EFBFBD>, <20>籸<EFBFBD><E7B1B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD><C7B4>Ѵ<EFBFBD>.
|
||||
if ( m_pParent && !HasSphereNodeFlag( SNF_INTEGRATE ) )
|
||||
{
|
||||
// <20>θ<EFBFBD><CEB8><EFBFBD><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
float fDistance2 = Distance2( m_pParent );
|
||||
|
||||
// <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD>ε<EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
if ( fDistance2 >= m_fBindingDistance2 )
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7>װ<EFBFBD> <20><><EFBFBD>ٸ<EFBFBD>, <20>θ<EFBFBD><CEB8><EFBFBD> ũ<>Ⱑ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
if ( !m_pParent->HasSphereNodeFlag( SNF_RECOMPUTE ) )
|
||||
{
|
||||
m_pTree->AddRecompute( m_pParent );
|
||||
}
|
||||
|
||||
// <20>θ<EFBFBD><CEB8><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20>ش<EFBFBD> Root <20><><EFBFBD>忡 <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
Unlink();
|
||||
m_pTree->AddIntegrate( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereNode::NewPos( float fX, float fY, float fZ )
|
||||
{
|
||||
NewPos( Position(fX, fY, fZ) );
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereNode::NewPosRadius( const Position& Pos, float fRadius )
|
||||
{
|
||||
// <20><><EFBFBD>ο<EFBFBD> <20><>ǥ <20><><EFBFBD><EFBFBD>
|
||||
m_Center = Pos;
|
||||
|
||||
// <20>θ<EFBFBD><CEB8><EFBFBD> <20>ְ<EFBFBD>, <20>籸<EFBFBD><E7B1B8><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD> <20><> <20>÷<EFBFBD><C3B7>װ<EFBFBD> <20><><EFBFBD>ٸ<EFBFBD>, <20>籸<EFBFBD><E7B1B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD><C7B4>Ѵ<EFBFBD>.
|
||||
if ( m_pParent && !HasSphereNodeFlag( SNF_INTEGRATE ) )
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ<C3BC>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE>ٸ<EFBFBD>,
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD>, <20><><EFBFBD>ε<EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
if ( fRadius != GetRadius() )
|
||||
{
|
||||
SetRadius( fRadius );
|
||||
ComputeBindingDistance( m_pParent );
|
||||
}
|
||||
|
||||
// <20>θ<EFBFBD><CEB8><EFBFBD><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
float fDistance2 = Distance2( m_pParent );
|
||||
|
||||
// <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD>ε<EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
if ( fDistance2 >= m_fBindingDistance2 )
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7>װ<EFBFBD> <20><><EFBFBD>ٸ<EFBFBD>, <20>θ<EFBFBD><CEB8><EFBFBD> ũ<>Ⱑ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
if ( !m_pParent->HasSphereNodeFlag( SNF_RECOMPUTE ) )
|
||||
{
|
||||
m_pTree->AddRecompute( m_pParent );
|
||||
}
|
||||
|
||||
// <20>θ<EFBFBD><CEB8><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20>ش<EFBFBD> Root <20><><EFBFBD>忡 <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
Unlink();
|
||||
m_pTree->AddIntegrate( this );
|
||||
}
|
||||
// <20>ڽ<EFBFBD><DABD><EFBFBD> <20>θ<EFBFBD><CEB8><EFBFBD> <20><><EFBFBD>ε<EFBFBD> <20>Ÿ<EFBFBD><C5B8>ȿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
else
|
||||
{
|
||||
// <20>θ<EFBFBD><CEB8><EFBFBD> <20><><EFBFBD>ε<EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><><EFBFBD>ϼ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ֱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
if ( !m_pParent->HasSphereNodeFlag( SNF_RECOMPUTE ) )
|
||||
{
|
||||
m_pTree->AddRecompute( m_pParent );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereNode::NewPosRadius( float fX, float fY, float fZ, float fRadius )
|
||||
{
|
||||
NewPosRadius( Position(fX, fY, fZ), fRadius );
|
||||
}
|
||||
|
||||
float
|
||||
CCharSphereNode::Distance2( const CCharSphereNode* pNode )
|
||||
{
|
||||
return static_cast<float>( m_Center.GetSquaredDistance( pNode->GetCenter() ) );
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereNode::ComputeBindingDistance( const CCharSphereNode* pParent )
|
||||
{
|
||||
m_fBindingDistance2 = pParent->GetRadius() - GetRadius();
|
||||
if ( m_fBindingDistance2 <= 0 ) m_fBindingDistance2 = 0;
|
||||
else m_fBindingDistance2 *= m_fBindingDistance2;
|
||||
}
|
||||
|
||||
bool
|
||||
CCharSphereNode::Recompute( float fGravy )
|
||||
{
|
||||
if ( !m_pChildren ) return true; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
if ( HasSphereNodeFlag( SNF_ROOT_NODE ) ) return false; // Root <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
|
||||
|
||||
Position sumPos;
|
||||
int iCount = 0;
|
||||
|
||||
// <20>ڽĵ<DABD><C4B5><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ؼ<EFBFBD>,
|
||||
// <20><><EFBFBD>ο<EFBFBD> <20>߽<EFBFBD> <20><>ǥ<EFBFBD><C7A5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
CCharSphereNode* pChild = m_pChildren;
|
||||
while ( pChild )
|
||||
{
|
||||
sumPos.m_fPointX += pChild->GetCenter().m_fPointX;
|
||||
sumPos.m_fPointY += pChild->GetCenter().m_fPointY;
|
||||
sumPos.m_fPointZ += pChild->GetCenter().m_fPointZ;
|
||||
|
||||
++iCount;
|
||||
|
||||
pChild = pChild->GetNextSibling();
|
||||
}
|
||||
|
||||
if ( iCount )
|
||||
{
|
||||
float fRecip = 1.0f / float(iCount);
|
||||
sumPos.m_fPointX *= fRecip;
|
||||
sumPos.m_fPointY *= fRecip;
|
||||
sumPos.m_fPointZ *= fRecip;
|
||||
|
||||
Position oldCenter = m_Center;
|
||||
m_Center = sumPos; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߽<EFBFBD> <20><>ǥ<EFBFBD><C7A5> <20><><EFBFBD><EFBFBD>
|
||||
float fMaxRadius = 0;
|
||||
|
||||
// <20>ڽĵ<DABD><C4B5><EFBFBD> <20><><EFBFBD>ԵǴ°<C7B4> Ȯ<><C8AE><EFBFBD>Ѵ<EFBFBD>.
|
||||
pChild = m_pChildren;
|
||||
while ( pChild )
|
||||
{
|
||||
float fDistance2 = Distance2( pChild );
|
||||
float fRadius = sqrtf( fDistance2 ) + pChild->GetRadius();
|
||||
|
||||
if ( fRadius > fMaxRadius )
|
||||
{
|
||||
fMaxRadius = fRadius;
|
||||
if ( (fMaxRadius + fGravy) >= GetRadius() )
|
||||
{
|
||||
m_Center = oldCenter;
|
||||
ClearShpereNodeFlag( SNF_RECOMPUTE );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
pChild = pChild->GetNextSibling();
|
||||
}
|
||||
|
||||
// <20><> Ŀ<><C4BF> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
|
||||
fMaxRadius += fGravy;
|
||||
SetRadius( fMaxRadius );
|
||||
|
||||
// <20>ڽĵ<DABD><C4B5><EFBFBD> <20><><EFBFBD>ε<EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
|
||||
pChild = m_pChildren;
|
||||
while ( pChild )
|
||||
{
|
||||
pChild->ComputeBindingDistance( this );
|
||||
pChild = pChild->GetNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
ClearShpereNodeFlag( SNF_RECOMPUTE );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
CCharSphereTree::CCharSphereTree( int iMaxSphereNode, float fRootSize, float fLeafSize, float fGravy ) :
|
||||
m_fMaxRootSize(fRootSize), m_fMaxLeafSize(fLeafSize), m_fSuperSphereGravy(fGravy)
|
||||
{
|
||||
iMaxSphereNode *= 4;
|
||||
m_Recompute = new CCharSphereNodeFifo( iMaxSphereNode );
|
||||
m_Integrate = new CCharSphereNodeFifo( iMaxSphereNode );
|
||||
|
||||
// Root Tree <20><><EFBFBD><EFBFBD>
|
||||
Position rootPos;
|
||||
m_pRoot = new CCharSphereNode();
|
||||
m_pRoot->Init( this, rootPos, 65535, NULL );
|
||||
m_pRoot->SetSphereNodeFlag( eSphereNodeFlag(SNF_ROOT_NODE | SNF_SUPERSPHERE | SNF_ROOT_TREE) );
|
||||
|
||||
// Leaf Tree <20><><EFBFBD><EFBFBD>
|
||||
m_pLeaf = new CCharSphereNode();
|
||||
m_pLeaf->Init( this, rootPos, 16384, NULL );
|
||||
m_pLeaf->SetSphereNodeFlag( eSphereNodeFlag(SNF_ROOT_NODE | SNF_SUPERSPHERE | SNF_LEAF_TREE) );
|
||||
}
|
||||
|
||||
CCharSphereTree::~CCharSphereTree()
|
||||
{
|
||||
DeleteAllChildSphere( m_pRoot );
|
||||
DeleteAllChildSphere( m_pLeaf );
|
||||
|
||||
SAFE_DELETE( m_pRoot );
|
||||
SAFE_DELETE( m_pLeaf );
|
||||
|
||||
SAFE_DELETE( m_Recompute );
|
||||
SAFE_DELETE( m_Integrate );
|
||||
|
||||
m_CharSphereMap.clear();
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereTree::Process()
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD> <20><> <20><><EFBFBD>Ͽ<EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD>带 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
// <20><><EFBFBD><EFBFBD> leaf node <20><> <20>θ<EFBFBD><CEB8><EFBFBD> <20><><EFBFBD><EFBFBD>ٸ<EFBFBD>, <20>θ<EFBFBD><CEB8><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ǰų<C7B0>, <20>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD>, <20><><EFBFBD>ŵǾ<C5B5><C7BE><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
if ( m_Recompute->GetCount() > 0 )
|
||||
{
|
||||
bool bKill;
|
||||
CCharSphereNode* pTempNode = NULL;
|
||||
|
||||
int iCount = m_Recompute->GetCount();
|
||||
for (int i=0; i<iCount; ++i)
|
||||
{
|
||||
pTempNode = m_Recompute->Pop();
|
||||
if ( !pTempNode ) continue;
|
||||
pTempNode->SetRecomputeFifo( NULL );
|
||||
|
||||
bKill = pTempNode->Recompute( m_fSuperSphereGravy );
|
||||
if ( bKill )
|
||||
{
|
||||
DeleteSphere( pTempNode );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <20>籸<EFBFBD><E7B1B8> <20>Ǿ<EFBFBD><C7BE><EFBFBD> <20><> <20><><EFBFBD>Ͽ<EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD>带 <20>籸<EFBFBD><E7B1B8><EFBFBD>Ѵ<EFBFBD>.
|
||||
if ( m_Integrate->GetCount() > 0 )
|
||||
{
|
||||
CCharSphereNode* pTempNode = NULL;
|
||||
|
||||
int iCount = m_Integrate->GetCount();
|
||||
for (int i=0; i<iCount; ++i)
|
||||
{
|
||||
pTempNode = m_Integrate->Pop();
|
||||
if ( !pTempNode ) continue;
|
||||
pTempNode->SetIntegrateFifo( NULL );
|
||||
|
||||
if ( pTempNode->HasSphereNodeFlag( SNF_ROOT_TREE ) )
|
||||
Integrate( pTempNode, m_pRoot, m_fMaxRootSize ); // integrate this one single dude against the root node.
|
||||
else
|
||||
Integrate( pTempNode, m_pLeaf, m_fMaxLeafSize ); // integrate this one single dude against the root node.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CCharSphereTree::AddCharacter( unsigned long dwCID, CCharacter* pCharacter, const Position& Pos )
|
||||
{
|
||||
CCharSphereNode* pNode = AddSphere( Pos, SphereConst::CHAR_RADIUS, NULL );
|
||||
if ( pNode )
|
||||
{
|
||||
pNode->SetCID( dwCID );
|
||||
pNode->SetCharacter( pCharacter );
|
||||
pNode->SetSphereNodeFlag( SNF_ACTOR_NODE );
|
||||
|
||||
return m_CharSphereMap.insert( std::make_pair(dwCID, pNode) ).second;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CCharSphereTree::DeleteCharacter( unsigned long dwCID )
|
||||
{
|
||||
CharSphereMap::iterator itr = m_CharSphereMap.find( dwCID );
|
||||
if ( itr != m_CharSphereMap.end() )
|
||||
{
|
||||
CCharSphereNode* pNode = itr->second;
|
||||
if ( pNode )
|
||||
{
|
||||
DeleteSphere( pNode );
|
||||
}
|
||||
|
||||
m_CharSphereMap.erase( itr );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereTree::MoveTo( unsigned long dwCID, const Position& NewPos )
|
||||
{
|
||||
CharSphereMap::iterator itr = m_CharSphereMap.find( dwCID );
|
||||
if ( itr != m_CharSphereMap.end() )
|
||||
{
|
||||
CCharSphereNode* pNode = itr->second;
|
||||
if ( pNode && pNode->GetCenter() != NewPos )
|
||||
{
|
||||
pNode->NewPos( NewPos );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCharSphereNode*
|
||||
CCharSphereTree::AddSphere( const Position& Pos, float fRadius, void* pLink, unsigned long dwFlag )
|
||||
{
|
||||
// <20><><EFBFBD>ο<EFBFBD> <20><><EFBFBD>带 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
CCharSphereNode* pNode = new CCharSphereNode();
|
||||
assert( pNode );
|
||||
|
||||
if ( pNode )
|
||||
{
|
||||
// Root <20><> Leaf <20>߿<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF>ְ<EFBFBD>, <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ִ´<D6B4>.
|
||||
if ( dwFlag & SNF_ROOT_TREE )
|
||||
{
|
||||
pNode->Init( this, Pos, fRadius, pLink );
|
||||
pNode->SetSphereNodeFlag( SNF_ROOT_TREE );
|
||||
AddIntegrate( pNode );
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode->Init( this, Pos, fRadius, pLink );
|
||||
pNode->SetSphereNodeFlag( SNF_LEAF_TREE );
|
||||
AddIntegrate( pNode );
|
||||
}
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereTree::DeleteSphere( CCharSphereNode* pNode )
|
||||
{
|
||||
// Root node <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
|
||||
if ( pNode->HasSphereNodeFlag( SNF_ROOT_NODE ) ) return;
|
||||
|
||||
// Leaf node tree <20><> supersphere <20><> <20><>ũ<EFBFBD><C5A9> root node tree <20><> node <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
|
||||
if ( pNode->HasSphereNodeFlag( SNF_SUPERSPHERE ) && pNode->HasSphereNodeFlag( SNF_LEAF_TREE) )
|
||||
{
|
||||
CCharSphereNode* pLink = (CCharSphereNode*) pNode->GetLink();
|
||||
DeleteSphere( pLink );
|
||||
}
|
||||
|
||||
pNode->Unlink();
|
||||
SAFE_DELETE( pNode );
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereTree::DeleteAllChildSphere( CCharSphereNode* pRootNode )
|
||||
{
|
||||
CCharSphereNode* pTempNode = NULL;
|
||||
CCharSphereNode* pChild = pRootNode->GetChildren();
|
||||
while ( pChild )
|
||||
{
|
||||
if ( pChild->GetChildCount() )
|
||||
{
|
||||
DeleteAllChildSphere( pChild );
|
||||
}
|
||||
|
||||
pTempNode = pChild;
|
||||
pChild = pChild->GetNextSibling();
|
||||
|
||||
SAFE_DELETE( pTempNode );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereTree::AddRecompute( CCharSphereNode* pNode )
|
||||
{
|
||||
if ( !pNode->HasSphereNodeFlag( SNF_RECOMPUTE ) )
|
||||
{
|
||||
if ( pNode->GetChildCount() )
|
||||
{
|
||||
pNode->SetSphereNodeFlag( SNF_RECOMPUTE );
|
||||
CCharSphereNode** ppFifo = m_Recompute->Push( pNode );
|
||||
pNode->SetRecomputeFifo( ppFifo );
|
||||
}
|
||||
else
|
||||
{
|
||||
DeleteSphere( pNode );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereTree::AddIntegrate( CCharSphereNode* pNode )
|
||||
{
|
||||
if ( pNode->HasSphereNodeFlag( SNF_ROOT_TREE ) )
|
||||
{
|
||||
m_pRoot->AddChild( pNode );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLeaf->AddChild( pNode );
|
||||
}
|
||||
|
||||
pNode->SetSphereNodeFlag( SNF_INTEGRATE );
|
||||
CCharSphereNode** ppFifo = m_Integrate->Push( pNode );
|
||||
pNode->SetIntegrateFifo( ppFifo );
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereTree::Integrate( CCharSphereNode* pNode, CCharSphereNode* pSuperSphere, float fNodeSize )
|
||||
{
|
||||
// <20>籸<EFBFBD><E7B1B8> <20>ܰ<EFBFBD> ù<><C3B9>°<EFBFBD><C2B0> pNode <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> SuperSphere <20><> ã<>´<EFBFBD>.
|
||||
CCharSphereNode* pSearch = pSuperSphere->GetChildren();
|
||||
|
||||
CCharSphereNode* pNearestNode1st = NULL; // pNode <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ѷ<EFBFBD><D1B7>Ҽ<EFBFBD> <20>ִ<EFBFBD> SuperSphere
|
||||
CCharSphereNode* pNearestNode2nd = NULL; // pNode <20><> <20>߰<EFBFBD><DFB0>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ణ ũ<>⸦ <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>ϴ<EFBFBD> SuperSphere
|
||||
float fNearDist1st2 = 1e9;
|
||||
float fNearDist2nd2 = 1e9;
|
||||
|
||||
while ( pSearch )
|
||||
{
|
||||
if ( !pSearch->HasSphereNodeFlag( SNF_ROOT_NODE ) &&
|
||||
pSearch->HasSphereNodeFlag( SNF_SUPERSPHERE ) &&
|
||||
pSearch->GetChildCount() )
|
||||
{
|
||||
float fDistance2 = pNode->Distance2( pSearch );
|
||||
|
||||
if ( pNearestNode1st )
|
||||
{
|
||||
// ã<><C3A3> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> SuperSphere <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>༮<EFBFBD><E0BCAE> ã<><C3A3> <20><><EFBFBD><EFBFBD>
|
||||
if ( fDistance2 < fNearDist1st2 )
|
||||
{
|
||||
float fDist = sqrtf( fDistance2 ) + pNode->GetRadius();
|
||||
if ( fDist <= pSearch->GetRadius() )
|
||||
{
|
||||
pNearestNode1st = pSearch;
|
||||
fNearDist1st2 = fDistance2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float fDist = sqrtf( fDistance2 ) + pNode->GetRadius() - pSearch->GetRadius();
|
||||
if ( fDist < fNearDist2nd2 )
|
||||
{
|
||||
if ( fDist < 0 )
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> SuperSphere <20><> ã<><C3A3> <20><><EFBFBD><EFBFBD>
|
||||
pNearestNode1st = pSearch;
|
||||
fNearDist1st2 = fDistance2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ű<><C5B0><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD>
|
||||
// <20><><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD> <20>ִ<EFBFBD> SuperSphere <20><> ã<><C3A3> <20><><EFBFBD><EFBFBD>
|
||||
pNearestNode2nd = pSearch;
|
||||
fNearDist2nd2 = fDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pSearch = pSearch->GetNextSibling();
|
||||
}
|
||||
|
||||
// pNode <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD> SuperSphere <20><> ã<><C3A3> <20><><EFBFBD><EFBFBD>
|
||||
if ( pNearestNode1st )
|
||||
{
|
||||
// pNode <20><> pNearestNode1st <20><> <20>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF>ָ<EFBFBD> <20>ȴ<EFBFBD>.
|
||||
pNode->Unlink();
|
||||
pNearestNode1st->AddChild( pNode );
|
||||
pNearestNode1st->Recompute( m_fSuperSphereGravy );
|
||||
pNode->ComputeBindingDistance( pNearestNode1st );
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> leaf node <20><> supersphere <20><><EFBFBD><EFBFBD>, root tree <20><> link node <20><><EFBFBD><EFBFBD> <20><>ǥ<EFBFBD><C7A5> ũ<>⸦ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
|
||||
if ( pNearestNode1st->HasSphereNodeFlag( SNF_LEAF_TREE ) )
|
||||
{
|
||||
CCharSphereNode* pLink = (CCharSphereNode*) pNearestNode1st->GetLink();
|
||||
pLink->NewPosRadius( pNearestNode1st->GetCenter(), pNearestNode1st->GetRadius() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bCreateNewSphere = true;
|
||||
|
||||
// ũ<>⸦ <20>ణ Ű<><C5B0><EFBFBD><EFBFBD> pNode <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SuperSphere <20><> ã<><C3A3> <20><><EFBFBD><EFBFBD>
|
||||
if ( pNearestNode2nd )
|
||||
{
|
||||
float fNewSize = fNearDist2nd2 + pNearestNode2nd->GetRadius() + m_fSuperSphereGravy;
|
||||
|
||||
if ( fNewSize <= fNodeSize )
|
||||
{
|
||||
pNode->Unlink();
|
||||
|
||||
pNearestNode2nd->SetRadius( fNewSize );
|
||||
pNearestNode2nd->AddChild( pNode );
|
||||
pNearestNode2nd->Recompute( m_fSuperSphereGravy );
|
||||
pNode->ComputeBindingDistance( pNearestNode2nd );
|
||||
|
||||
if ( pNearestNode2nd->HasSphereNodeFlag( SNF_LEAF_TREE ) )
|
||||
{
|
||||
CCharSphereNode* pLink = (CCharSphereNode*) pNearestNode2nd->GetLink();
|
||||
pLink->NewPosRadius( pNearestNode2nd->GetCenter(), pNearestNode2nd->GetRadius() );
|
||||
}
|
||||
|
||||
bCreateNewSphere = false;
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ο<EFBFBD> SuperSphere <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
if ( bCreateNewSphere )
|
||||
{
|
||||
assert( pSuperSphere->HasSphereNodeFlag( SNF_ROOT_NODE ) );
|
||||
|
||||
pNode->Unlink();
|
||||
|
||||
CCharSphereNode* pParent = new CCharSphereNode();
|
||||
assert( pParent );
|
||||
pParent->Init( this, pNode->GetCenter(), pNode->GetRadius() + m_fSuperSphereGravy, NULL );
|
||||
|
||||
if ( pSuperSphere->HasSphereNodeFlag( SNF_ROOT_TREE ) )
|
||||
{
|
||||
pParent->SetSphereNodeFlag( eSphereNodeFlag(SNF_SUPERSPHERE | SNF_ROOT_TREE) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pParent->SetSphereNodeFlag( eSphereNodeFlag(SNF_SUPERSPHERE | SNF_LEAF_TREE) );
|
||||
}
|
||||
|
||||
pParent->AddChild( pNode );
|
||||
pSuperSphere->AddChild( pParent );
|
||||
pParent->Recompute( m_fSuperSphereGravy );
|
||||
pNode->ComputeBindingDistance( pParent );
|
||||
|
||||
if ( pParent->HasSphereNodeFlag( SNF_LEAF_TREE ) )
|
||||
{
|
||||
// root node <20><> link <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
CCharSphereNode* pLink = AddSphere( pParent->GetCenter(), pParent->GetRadius(), pParent, SNF_ROOT_TREE );
|
||||
pParent->SetLink( pLink );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pNode->ClearShpereNodeFlag( SNF_INTEGRATE );
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereNode::RangeTest( const Position& centerPos, float fDistance, ICharSphereTreeCallBack* pCallBack )
|
||||
{
|
||||
float fDist = static_cast<float>( m_Center.GetDistance( centerPos ) );
|
||||
if ( (fDist - fDistance) > GetRadius() ) return;
|
||||
|
||||
if ( HasSphereNodeFlag( SNF_SUPERSPHERE ) )
|
||||
{
|
||||
CCharSphereNode* pNode = m_pChildren;
|
||||
while ( pNode )
|
||||
{
|
||||
pNode->RangeTest( centerPos, fDistance, pCallBack );
|
||||
pNode = pNode->GetNextSibling();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( HasSphereNodeFlag( SNF_ROOT_TREE ) )
|
||||
{
|
||||
CCharSphereNode* pLink = (CCharSphereNode*) GetLink();
|
||||
if ( pLink )
|
||||
{
|
||||
pLink->RangeTest( centerPos, fDistance, pCallBack ) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pCallBack->RangeTestCallBack( centerPos, fDistance, this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereTree::RangeTest( const Position& centerPos, float fDistance, ICharSphereTreeCallBack* pCallBack )
|
||||
{
|
||||
m_pRoot->RangeTest( centerPos, fDistance, pCallBack );
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereNode::SendToRange( const Position& centerPos, float fDistance, const char* szPacket, unsigned long dwPacketSize, unsigned char cCMD_In )
|
||||
{
|
||||
float fDist = static_cast<float>( m_Center.GetDistance( centerPos ) );
|
||||
if ( (fDist - fDistance) > GetRadius() ) return;
|
||||
|
||||
if ( HasSphereNodeFlag( SNF_SUPERSPHERE ) )
|
||||
{
|
||||
CCharSphereNode* pNode = m_pChildren;
|
||||
while ( pNode )
|
||||
{
|
||||
pNode->SendToRange( centerPos, fDistance, szPacket, dwPacketSize, cCMD_In );
|
||||
pNode = pNode->GetNextSibling();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( HasSphereNodeFlag( SNF_ROOT_TREE ) )
|
||||
{
|
||||
CCharSphereNode* pLink = (CCharSphereNode*) GetLink();
|
||||
if ( pLink )
|
||||
{
|
||||
pLink->SendToRange( centerPos, fDistance, szPacket, dwPacketSize, cCMD_In ) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Packet <20><><EFBFBD><EFBFBD>
|
||||
if (NULL != m_pCharacter)
|
||||
{
|
||||
CGameClientDispatch* lpDispatcher = m_pCharacter->GetDispatcher();
|
||||
if (NULL != lpDispatcher)
|
||||
{
|
||||
lpDispatcher->GetSendStream().PutBuffer( szPacket, dwPacketSize, cCMD_In );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCharSphereTree::SendToRange( const Position& centerPos, float fDistance, const char* szPacket, unsigned long dwPacketSize, unsigned char cCMD_In )
|
||||
{
|
||||
m_pRoot->SendToRange( centerPos, fDistance, szPacket, dwPacketSize, cCMD_In );
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
#ifndef __CHARACTER_SPHERE_TREE_H__
|
||||
#define __CHARACTER_SPHERE_TREE_H__
|
||||
|
||||
#include "Sphere.h"
|
||||
#include "CharSphereTreeConstants.h"
|
||||
using namespace SphereConst;
|
||||
|
||||
#include <map>
|
||||
|
||||
#ifndef SAFE_DELETE
|
||||
#define SAFE_DELETE(p) { if ((p)) { delete (p); (p) = NULL; } }
|
||||
#endif
|
||||
|
||||
#ifndef SAFE_DELETE_ARRAY
|
||||
#define SAFE_DELETE_ARRAY(p) { if ((p)) { delete [] (p); (p) = NULL; } }
|
||||
#endif
|
||||
|
||||
//======================================================================================
|
||||
struct Position;
|
||||
class CCharacter;
|
||||
class CSphere;
|
||||
class CCharSphereNode;
|
||||
class CCharSphereTree;
|
||||
class CCharSphereNodeFifo;
|
||||
class ICharSphereTreeCallBack;
|
||||
|
||||
//======================================================================================
|
||||
class ICharSphereTreeCallBack
|
||||
{
|
||||
public:
|
||||
virtual void RangeTestCallBack( const Position& centerPos, float fDistance, CCharSphereNode* pNode )
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
//======================================================================================
|
||||
class CCharSphereNode : public CSphere
|
||||
{
|
||||
public:
|
||||
CCharSphereNode();
|
||||
CCharSphereNode( CCharSphereTree* pTree, const Position& Pos, float fRadius, void* pLink );
|
||||
|
||||
void Init( CCharSphereTree* pTree, const Position& Pos, float fRadius, void* pLink );
|
||||
|
||||
// ===================================================================
|
||||
// Flag <20>Լ<EFBFBD>
|
||||
void SetSphereNodeFlag( eSphereNodeFlag flag ) { m_dwFlag |= flag; }
|
||||
void ClearShpereNodeFlag( eSphereNodeFlag flag ) { m_dwFlag &= ~flag; }
|
||||
bool HasSphereNodeFlag( eSphereNodeFlag flag ) const
|
||||
{
|
||||
if ( m_dwFlag & flag ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>
|
||||
void SetCID( unsigned long dwCID ) { m_dwCID = dwCID; }
|
||||
unsigned long GetCID() const { return m_dwCID; }
|
||||
void SetCharacter(CCharacter* pCharacter) { m_pCharacter = pCharacter; }
|
||||
CCharacter* GetCharacter() const { return m_pCharacter; }
|
||||
|
||||
// ===================================================================
|
||||
// <20>θ<EFBFBD> & <20>ڽ<EFBFBD> <20>Լ<EFBFBD>
|
||||
void SetParent( CCharSphereNode* pParent ) { m_pParent = pParent; }
|
||||
CCharSphereNode* GetParent() const { return m_pParent; }
|
||||
|
||||
void AddChild( CCharSphereNode* pChild );
|
||||
void DeleteChild( CCharSphereNode* pChild );
|
||||
CCharSphereNode* GetChildren() const { return m_pChildren; }
|
||||
int GetChildCount() const { return m_iChildCount; }
|
||||
|
||||
// ===================================================================
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>
|
||||
void SetPrevSibling( CCharSphereNode* pNode ) { m_pPrevSibling = pNode; }
|
||||
void SetNextSibling( CCharSphereNode* pNode ) { m_pNextSibling = pNode; }
|
||||
CCharSphereNode* GetPrevSibling() const { return m_pPrevSibling; }
|
||||
CCharSphereNode* GetNextSibling() const { return m_pNextSibling; }
|
||||
|
||||
// ===================================================================
|
||||
// Fifo <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>
|
||||
void SetRecomputeFifo( CCharSphereNode** ppFifo ) { m_ppRecomuteFifo = ppFifo; }
|
||||
void SetIntegrateFifo( CCharSphereNode** ppFifo ) { m_ppIntegrateFifo = ppFifo; }
|
||||
|
||||
// ===================================================================
|
||||
// <20>θ<EFBFBD><CEB8><EFBFBD> <20>ڽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD> <20>θ<EFBFBD><CEB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>´<EFBFBD>.)
|
||||
void Unlink();
|
||||
|
||||
// ===================================================================
|
||||
// Root tree node <20><> Link ( Leaf tree <20><> Root <20><> <20>ƴ<EFBFBD> SuperSphere node <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> )
|
||||
void SetLink( void* pLink ) { m_pLink = pLink; }
|
||||
void* GetLink() const { return m_pLink; }
|
||||
|
||||
// ===================================================================
|
||||
// <20><>ǥ <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>
|
||||
void NewPos( const Position& Pos );
|
||||
void NewPos( float fX, float fY, float fZ );
|
||||
void NewPosRadius( const Position& Pos, float fRadius );
|
||||
void NewPosRadius( float fX, float fY, float fZ, float fRadius );
|
||||
|
||||
// ===================================================================
|
||||
// <20>Ÿ<EFBFBD> <20><> <20><><EFBFBD>ε<EFBFBD><CEB5>Ÿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>
|
||||
float Distance2( const CCharSphereNode* pNode );
|
||||
void ComputeBindingDistance( const CCharSphereNode* pParent );
|
||||
|
||||
// ===================================================================
|
||||
// ũ<><C5A9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Լ<EFBFBD> ( true <20><><EFBFBD>Ͻÿ<CFBD><C3BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD><D8BE><EFBFBD> )
|
||||
bool Recompute( float fGravy );
|
||||
|
||||
// ===================================================================
|
||||
// <20><><EFBFBD><EFBFBD> <20><EFBFBD>Ʈ<EFBFBD><C6AE> <20>Լ<EFBFBD>
|
||||
void RangeTest( const Position& centerPos, float fDistance, ICharSphereTreeCallBack* pCallBack );
|
||||
void SendToRange( const Position& centerPos, float fDistance, const char* szPacket,
|
||||
unsigned long dwPacketSize, unsigned char cCMD_In );
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
unsigned long m_dwCID;
|
||||
CCharacter* m_pCharacter;
|
||||
|
||||
CCharSphereNode* m_pParent;
|
||||
CCharSphereNode* m_pChildren;
|
||||
|
||||
CCharSphereNode* m_pPrevSibling;
|
||||
CCharSphereNode* m_pNextSibling;
|
||||
|
||||
CCharSphereNode** m_ppRecomuteFifo; // Recompute Fifo <20><><EFBFBD><EFBFBD> <20><>ġ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
CCharSphereNode** m_ppIntegrateFifo; // Integrate Fifo <20><><EFBFBD><EFBFBD> <20><>ġ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
int m_iChildCount;
|
||||
unsigned long m_dwFlag;
|
||||
float m_fBindingDistance2;
|
||||
|
||||
void* m_pLink;
|
||||
CCharSphereTree* m_pTree;
|
||||
};
|
||||
|
||||
|
||||
//======================================================================================
|
||||
class CCharSphereTree
|
||||
{
|
||||
public:
|
||||
CCharSphereTree( int iMaxSphereNode, float fRootSize, float fLeafSize, float fGravy );
|
||||
virtual ~CCharSphereTree();
|
||||
|
||||
typedef std::map< unsigned long, CCharSphereNode* > CharSphereMap;
|
||||
|
||||
static CCharSphereTree& GetInstance();
|
||||
|
||||
// ===================================================================
|
||||
// Tree <20><> Node <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20>籸<EFBFBD><E7B1B8><EFBFBD>ϴ<EFBFBD> ó<><C3B3> <20>Լ<EFBFBD>
|
||||
void Process();
|
||||
|
||||
// ===================================================================
|
||||
// ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>
|
||||
bool AddCharacter( unsigned long dwCID, CCharacter* pCharacter, const Position& Pos ) ;
|
||||
bool DeleteCharacter( unsigned long dwCID );
|
||||
void MoveTo( unsigned long dwCID, const Position& NewPos );
|
||||
|
||||
// ===================================================================
|
||||
// CCharSphereNode <20><> <20><><EFBFBD><EFBFBD>(ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)<29>ؼ<EFBFBD> <20>籸<EFBFBD><E7B1B8><EFBFBD>ϴ<EFBFBD> <20>Լ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>Լ<EFBFBD>
|
||||
CCharSphereNode* AddSphere( const Position& Pos, float fRadius, void* pLink, unsigned long dwFlag = SNF_LEAF_TREE );
|
||||
void DeleteSphere( CCharSphereNode* pNode );
|
||||
|
||||
// ===================================================================
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>籸<EFBFBD><E7B1B8> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> Node <20>߰<EFBFBD> <20>Լ<EFBFBD>
|
||||
void AddRecompute( CCharSphereNode* pNode );
|
||||
void AddIntegrate( CCharSphereNode* pNode );
|
||||
|
||||
// ===================================================================
|
||||
// Tree <20><> <20>籸<EFBFBD><E7B1B8><EFBFBD>ϴ<EFBFBD> <20>Լ<EFBFBD>
|
||||
void Integrate( CCharSphereNode* pNode, CCharSphereNode* pSuperSphere, float fNodeSize );
|
||||
|
||||
// ===================================================================
|
||||
// <20><><EFBFBD><EFBFBD> <20><EFBFBD>Ʈ<EFBFBD><C6AE> <20>Լ<EFBFBD>
|
||||
void RangeTest( const Position& centerPos, float fDistance, ICharSphereTreeCallBack* pCallBack );
|
||||
void SendToRange( const Position& centerPos, float fDistance, const char* szPacket,
|
||||
unsigned long dwPacketSize, unsigned char cCMD_In );
|
||||
|
||||
protected:
|
||||
// ===================================================================
|
||||
// <20><><EFBFBD><EFBFBD> <20>ڽ<EFBFBD> Node <20><> <20><EFBFBD><DEB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>Լ<EFBFBD>
|
||||
void DeleteAllChildSphere( CCharSphereNode* pRootNode );
|
||||
|
||||
private:
|
||||
CCharSphereNode* m_pRoot;
|
||||
CCharSphereNode* m_pLeaf;
|
||||
|
||||
CCharSphereNodeFifo* m_Recompute;
|
||||
CCharSphereNodeFifo* m_Integrate;
|
||||
|
||||
float m_fMaxRootSize;
|
||||
float m_fMaxLeafSize;
|
||||
float m_fSuperSphereGravy;
|
||||
|
||||
CharSphereMap m_CharSphereMap;
|
||||
};
|
||||
|
||||
|
||||
//======================================================================================
|
||||
class CCharSphereNodeFifo
|
||||
{
|
||||
public:
|
||||
CCharSphereNodeFifo( int iSize )
|
||||
{
|
||||
m_iCount = 0;
|
||||
m_iStackPointer = 0;
|
||||
m_iBottom = 0;
|
||||
m_iSize = iSize;
|
||||
m_ppFifo = new CCharSphereNode *[ m_iSize ];
|
||||
};
|
||||
|
||||
~CCharSphereNodeFifo()
|
||||
{
|
||||
SAFE_DELETE_ARRAY( m_ppFifo );
|
||||
};
|
||||
|
||||
CCharSphereNode** Push( CCharSphereNode* pNode )
|
||||
{
|
||||
m_iCount++;
|
||||
CCharSphereNode** ret = &m_ppFifo[ m_iStackPointer ];
|
||||
m_ppFifo[ m_iStackPointer ] = pNode;
|
||||
++m_iStackPointer;
|
||||
if ( m_iStackPointer == m_iSize ) m_iStackPointer = 0;
|
||||
return ret;
|
||||
};
|
||||
|
||||
CCharSphereNode* Pop()
|
||||
{
|
||||
while ( m_iStackPointer != m_iBottom )
|
||||
{
|
||||
--m_iCount;
|
||||
CCharSphereNode* ret = m_ppFifo[ m_iBottom ];
|
||||
++m_iBottom;
|
||||
if ( m_iBottom == m_iSize ) m_iBottom = 0;
|
||||
if ( ret ) return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool Flush( CCharSphereNode* pNode )
|
||||
{
|
||||
if ( m_iStackPointer == m_iBottom ) return false;
|
||||
int i = m_iBottom;
|
||||
while ( i != m_iStackPointer )
|
||||
{
|
||||
if ( m_ppFifo[i] == pNode )
|
||||
{
|
||||
m_ppFifo[i] = NULL;
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
if ( i == m_iSize ) i = 0;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
int GetCount(void) const { return m_iCount; }
|
||||
|
||||
private:
|
||||
|
||||
int m_iCount;
|
||||
int m_iStackPointer;
|
||||
int m_iBottom;
|
||||
int m_iSize;
|
||||
CCharSphereNode** m_ppFifo;
|
||||
};
|
||||
|
||||
|
||||
#endif __CHARACTER_SPHERE_TREE_H__
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef __SPHERE_TREE_CONST_H__
|
||||
#define __SPHERE_TREE_CONST_H__
|
||||
|
||||
namespace SphereConst
|
||||
{
|
||||
enum eSphereNodeFlag
|
||||
{
|
||||
SNF_ROOT_NODE = (1<<0), // this is the root node
|
||||
SNF_SUPERSPHERE = (1<<1), // this is a supersphere, allocated and deleted by us
|
||||
SNF_ACTOR_NODE = (1<<2), // this is real actor node
|
||||
SNF_ROOT_TREE = (1<<3), // member of the root tree
|
||||
SNF_LEAF_TREE = (1<<4), // member of the leaf node tree
|
||||
SNF_RECOMPUTE = (1<<5), // needs recomputed bounding sphere
|
||||
SNF_INTEGRATE = (1<<6) // needs to be reintegrated into tree
|
||||
};
|
||||
|
||||
enum eViewState
|
||||
{
|
||||
VS_INSIDE, // completely inside the frustum.
|
||||
VS_PARTIAL, // partially inside and partially outside the frustum.
|
||||
VS_OUTSIDE // completely outside the frustum
|
||||
};
|
||||
|
||||
enum eConst
|
||||
{
|
||||
CHAR_RADIUS = 2, // ij<><C4B3><EFBFBD><EFBFBD> <20>ݰ<EFBFBD> 2m
|
||||
MAX_SPHERE_NODE = 2000, // MAX 2000 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
DEFAULT_ROOT_SIZE = 256, // Root node <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
DEFAULT_LEAF_SIZE = 64, // Leaf node <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
DEFAULT_GRAVY = 15 // <20>θ<EFBFBD><CEB8><EFBFBD><EFBFBD><EFBFBD> <20>ڽĿ<DABD><C4BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
|
||||
};
|
||||
};
|
||||
|
||||
#endif __SPHERE_TREE_CONST_H__
|
||||
@@ -0,0 +1,214 @@
|
||||
#ifndef __SPHERE_H__
|
||||
#define __SPHERE_H__
|
||||
|
||||
#include <math.h>
|
||||
#include <Creature/CreatureStructure.h>
|
||||
|
||||
//======================================================================================
|
||||
// 3<><33><EFBFBD><EFBFBD> <20><>ǥ <20><><EFBFBD><EFBFBD>ü
|
||||
/*
|
||||
#ifndef EPSILON
|
||||
#define EPSILON 0.001
|
||||
#endif
|
||||
|
||||
struct sVector3
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
float v[3];
|
||||
};
|
||||
|
||||
sVector3()
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
}
|
||||
|
||||
sVector3( float fX, float fY, float fZ )
|
||||
{
|
||||
x = fX;
|
||||
y = fY;
|
||||
z = fZ;
|
||||
}
|
||||
|
||||
float Length() const
|
||||
{
|
||||
return sqrtf( x*x + y*y + z*z );
|
||||
}
|
||||
|
||||
float Distance( const sVector3& inPos ) const
|
||||
{
|
||||
sVector3 tempVector( inPos.x - x, inPos.y - y, inPos.z - z );
|
||||
return tempVector.Length();
|
||||
}
|
||||
|
||||
float Distance2( const sVector3& inPos ) const
|
||||
{
|
||||
return ( (inPos.x - x) * (inPos.x - x) + (inPos.y - y) * (inPos.y - y) + (inPos.z - z) * (inPos.z - z) );
|
||||
}
|
||||
|
||||
bool operator == ( const sVector3& inPos ) const
|
||||
{
|
||||
if ( fabs(x - inPos.x) <= EPSILON && fabs(y - inPos.y) <= EPSILON && fabs(z - inPos.z) <= EPSILON )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator != ( const sVector3& inPos ) const
|
||||
{
|
||||
if ( fabs(x - inPos.x) > EPSILON || fabs(y - inPos.y) > EPSILON || fabs(z - inPos.z) > EPSILON )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
//======================================================================================
|
||||
// <20>⺻ <20><> Ŭ<><C5AC><EFBFBD><EFBFBD>
|
||||
class CSphere
|
||||
{
|
||||
public:
|
||||
|
||||
CSphere();
|
||||
CSphere( float fX, float fY, float fZ, float fRadius );
|
||||
CSphere( const Position& inPos, float fRadius );
|
||||
|
||||
// ===============================================================
|
||||
void Set( float fX, float fY, float fZ, float fRadius );
|
||||
void Set( const Position& inPos, float fRadius );
|
||||
void SetRadius( float fRadius );
|
||||
|
||||
float GetX() const { return m_Center.m_fPointX; }
|
||||
float GetY() const { return m_Center.m_fPointY; }
|
||||
float GetZ() const { return m_Center.m_fPointZ; }
|
||||
const Position& GetCenter() const { return m_Center; }
|
||||
float GetRadius() const { return m_fRadius; }
|
||||
float GetRadius2() const { return m_fRadius2; }
|
||||
|
||||
// ===============================================================
|
||||
// 3<><33><EFBFBD><EFBFBD> <20><>ǥ<EFBFBD><C7A5> <20><><EFBFBD>ȿ<EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> <20>˻<EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> + fDistance <20>ȿ<EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> <20>˻縦 <20>Ѵ<EFBFBD>.
|
||||
bool InSphere( float fX, float fY, float fZ, float fDistance );
|
||||
bool InSphere( const Position& inPos, float fDistance );
|
||||
|
||||
// 2<><32><EFBFBD><EFBFBD> <20><>ǥ<EFBFBD><C7A5> <20><><EFBFBD>ȿ<EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> <20>˻<EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> + fDistance <20>ȿ<EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> <20>˻縦 <20>Ѵ<EFBFBD>.
|
||||
bool InSphereXY( float fX, float fY, float fDistance );
|
||||
bool InSphereXY( const Position& inPos, float fDistance );
|
||||
|
||||
protected:
|
||||
|
||||
Position m_Center; // <20><><EFBFBD><EFBFBD> <20>߽<EFBFBD> <20><>ǥ
|
||||
|
||||
private:
|
||||
|
||||
float m_fRadius; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
float m_fRadius2; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>
|
||||
};
|
||||
|
||||
inline
|
||||
CSphere::CSphere() :
|
||||
m_fRadius(0), m_fRadius2(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
CSphere::CSphere( float fX, float fY, float fZ, float fRadius ) :
|
||||
m_fRadius(fRadius), m_fRadius2(fRadius * fRadius)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
CSphere::CSphere( const Position& inPos, float fRadius ) :
|
||||
m_Center(inPos), m_fRadius(fRadius), m_fRadius2(fRadius * fRadius)
|
||||
{
|
||||
}
|
||||
|
||||
inline void
|
||||
CSphere::Set( float fX, float fY, float fZ, float fRadius )
|
||||
{
|
||||
m_Center.m_fPointX = fX;
|
||||
m_Center.m_fPointY = fY;
|
||||
m_Center.m_fPointZ = fZ;
|
||||
|
||||
m_fRadius = fRadius;
|
||||
m_fRadius2 = fRadius * fRadius;
|
||||
}
|
||||
|
||||
inline void
|
||||
CSphere::Set( const Position& inPos, float fRadius )
|
||||
{
|
||||
m_Center = inPos;
|
||||
|
||||
m_fRadius = fRadius;
|
||||
m_fRadius2 = fRadius * fRadius;
|
||||
}
|
||||
|
||||
inline void
|
||||
CSphere::SetRadius( float fRadius )
|
||||
{
|
||||
m_fRadius = fRadius;
|
||||
m_fRadius2 = fRadius * fRadius;
|
||||
}
|
||||
|
||||
inline bool
|
||||
CSphere::InSphere( float fX, float fY, float fZ, float fDistance )
|
||||
{
|
||||
float dx = fX - m_Center.m_fPointX;
|
||||
float dy = fY - m_Center.m_fPointY;
|
||||
float dz = fZ - m_Center.m_fPointZ;
|
||||
float dist = sqrtf( dx*dx + dy*dy + dz*dz );
|
||||
|
||||
if ( dist < (m_fRadius + fDistance) ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
CSphere::InSphere( const Position& inPos, float fDistance )
|
||||
{
|
||||
float dx = inPos.m_fPointX - m_Center.m_fPointX;
|
||||
float dy = inPos.m_fPointY - m_Center.m_fPointY;
|
||||
float dz = inPos.m_fPointZ - m_Center.m_fPointZ;
|
||||
float dist = sqrtf( dx*dx + dy*dy + dz*dz );
|
||||
|
||||
if ( dist < (m_fRadius + fDistance) ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
CSphere::InSphereXY( float fX, float fY, float fDistance )
|
||||
{
|
||||
float dx = fX - m_Center.m_fPointX;
|
||||
float dy = fY - m_Center.m_fPointY;
|
||||
float dist = sqrtf( dx*dx + dy*dy );
|
||||
|
||||
if ( dist < (m_fRadius + fDistance) ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
CSphere::InSphereXY( const Position& inPos, float fDistance )
|
||||
{
|
||||
float dx = inPos.m_fPointX - m_Center.m_fPointX;
|
||||
float dy = inPos.m_fPointY - m_Center.m_fPointY;
|
||||
float dist = sqrtf( dx*dx + dy*dy );
|
||||
|
||||
if ( dist < (m_fRadius + fDistance) ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif __SPHERE_H__
|
||||
Reference in New Issue
Block a user