#include "StdAfx.h" #include "PathNode.h" #include "TagStream.h" CPathNodeManager* CPathNodeManager::ms_pkThis = NULL; CPathNodeManager::CPathNodeManager() :m_uiPathNodeCount(0) ,m_pkPathNodes(NULL) ,m_uiTotalLinkCount(0) ,m_puiLinks(NULL) ,m_pfLinkLegnth(NULL) { NIASSERT(ms_pkThis == NULL); ms_pkThis = this; } CPathNodeManager::~CPathNodeManager() { Unload(); ms_pkThis = NULL; } void CPathNodeManager::Load(const NiFixedString& kMapName) { Unload(); char acFilename[NI_MAX_PATH]; NiSprintf(acFilename, NI_MAX_PATH, "Data\\World\\Maps\\%s\\%s.pth", (const char*)kMapName, (const char*)kMapName); NiFile* pkFile = NiFile::GetFile(acFilename, NiFile::READ_ONLY); if( !pkFile || !(*pkFile) ) { NiDelete pkFile; return; } CTagStream kStream; while( kStream.ReadFromStream( pkFile ) ) { switch( kStream.GetTag() ) { case 'NODE': { kStream.Read(&m_uiPathNodeCount, sizeof(unsigned int)); if(m_uiPathNodeCount > 0) { m_pkPathNodes = NiAlloc(CPathNode, m_uiPathNodeCount); kStream.Read(m_pkPathNodes, sizeof(CPathNode)*m_uiPathNodeCount); } kStream.Read(&m_uiTotalLinkCount, sizeof(unsigned int)); if(m_uiTotalLinkCount > 0) { m_puiLinks = NiAlloc(unsigned int, m_uiTotalLinkCount); kStream.Read(m_puiLinks, sizeof(unsigned int)*m_uiTotalLinkCount); CalcLinkLength(); } } break; } } NiDelete pkFile; } void CPathNodeManager::Unload() { if(m_uiPathNodeCount) { NiFree(m_pkPathNodes); m_pkPathNodes = NULL; m_uiPathNodeCount = 0; } if(m_uiTotalLinkCount) { NiFree(m_puiLinks); m_puiLinks = NULL; m_uiTotalLinkCount = 0; NiFree(m_pfLinkLegnth); m_pfLinkLegnth = NULL; } } //获取最近的Path Node, 如果场景没有Path Node 则返回NULL CPathNode* CPathNodeManager::GetNearestPathNode(const NiPoint3& kPos) const { CPathNode* pkPathNode = NULL; float fNearestLen = FLT_MAX; float fLen; //todo... 优化这里 for(unsigned int i = 0; i < m_uiPathNodeCount; ++i) { fLen = (m_pkPathNodes[i].m_kTranslate - kPos).SqrLength(); if(fLen < fNearestLen) { fNearestLen = fLen; pkPathNode = &m_pkPathNodes[i]; } } return pkPathNode; } //通过ID 获取PathNode CPathNode* CPathNodeManager::GetPathNode(unsigned int uiPathNodeId) { NIASSERT(uiPathNodeId < m_uiPathNodeCount); return &m_pkPathNodes[uiPathNodeId]; } //获取第idx个连接的PathNode CPathNode* CPathNodeManager::GetLinkPathNode(CPathNode* pkPathNode, unsigned int idx, float& fLength) { NIASSERT(pkPathNode); NIASSERT(idx < pkPathNode->m_uiLinkCount); NIASSERT(pkPathNode->m_uiFirstLink + idx < m_uiTotalLinkCount); CPathNode* pkLinkNode = GetPathNode(m_puiLinks[pkPathNode->m_uiFirstLink + idx]); if(pkLinkNode) fLength = m_pfLinkLegnth[pkPathNode->m_uiFirstLink + idx]; return pkLinkNode; } //计算每个连接的长度 void CPathNodeManager::CalcLinkLength() { m_pfLinkLegnth = NiAlloc(float, m_uiTotalLinkCount); CPathNode* pkPathNode; CPathNode* pkLinkNode; unsigned int k = 0; float fLength; for(unsigned int i = 0; i < m_uiPathNodeCount; ++i) { pkPathNode = &m_pkPathNodes[i]; for(unsigned int j = 0; j < pkPathNode->m_uiLinkCount; ++j) { pkLinkNode = GetLinkPathNode(pkPathNode, j, fLength); //m_pfLinkLegnth 还没有初始化 NIASSERT(pkLinkNode); NIASSERT(k == pkPathNode->m_uiFirstLink + j); m_pfLinkLegnth[k++] = (pkPathNode->m_kTranslate - pkLinkNode->m_kTranslate).Length(); } } }