1124 lines
30 KiB
C++
1124 lines
30 KiB
C++
|
|
#include "stdafx.h"
|
|
|
|
#include <toolkit/XStringUtil.h>
|
|
|
|
#include "MapDefine.h"
|
|
|
|
#include <kfile/KFileManager.h>
|
|
#include <kfile/KStream.h>
|
|
#include "PVSObject.h"
|
|
|
|
#ifdef _DEBUG
|
|
#ifdef _RAC
|
|
#include "SDebug_Util.h"
|
|
#else
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
#endif
|
|
|
|
|
|
PVSObject::PVSObject()
|
|
{
|
|
m_pHeader = NULL;
|
|
m_rcSegment = KRect(0,0,0,0);
|
|
}
|
|
|
|
PVSObject::~PVSObject()
|
|
{
|
|
SAFE_DELETE( m_pHeader );
|
|
|
|
{
|
|
SEGMENT_ROOT* pDATA=NULL;
|
|
bool res;
|
|
res = m_hashBySEGMENT.get_first_value( pDATA );
|
|
while ( res )
|
|
{
|
|
if ( pDATA != NULL )
|
|
{
|
|
delete pDATA;
|
|
}
|
|
res = m_hashBySEGMENT.get_next_value( pDATA );
|
|
}
|
|
m_hashBySEGMENT.clear();
|
|
}
|
|
|
|
{
|
|
PROP_ROOT* pDATA=NULL;
|
|
bool res;
|
|
res = m_hashByPROP.get_first_value( pDATA );
|
|
while ( res )
|
|
{
|
|
if ( pDATA != NULL )
|
|
{
|
|
delete pDATA;
|
|
}
|
|
res = m_hashByPROP.get_next_value( pDATA );
|
|
}
|
|
m_hashByPROP.clear();
|
|
}
|
|
}
|
|
|
|
bool PVSObject::IsMapCheck( int nMapStartX, int nMapStartY )
|
|
{
|
|
if( m_pHeader )
|
|
{
|
|
return ( m_pHeader->nMapStartPosX == nMapStartX && m_pHeader->nMapStartPosY == nMapStartY );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool PVSObject::IsPVSActCheck( int nRootSegmentX, int nRootSegmentY )
|
|
{
|
|
if( m_pHeader )
|
|
{
|
|
return ( nRootSegmentX >= m_rcSegment.left && nRootSegmentX <= m_rcSegment.right &&
|
|
nRootSegmentY >= m_rcSegment.top && nRootSegmentY <= m_rcSegment.bottom );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void PVSObject::Load( const char* pFileName )
|
|
{
|
|
KStream* pStream = KFileManager::Instance().CreateStreamFromResource( pFileName );
|
|
if( NULL == pStream )
|
|
{
|
|
return;
|
|
}
|
|
|
|
SAFE_DELETE( m_pHeader );
|
|
|
|
m_pHeader = new NFM_PVS_HEADER_V1;
|
|
pStream->Read( m_pHeader, sizeof(NFM_PVS_HEADER_V1) );
|
|
|
|
for( int i(0); m_pHeader->nSegmentCount>i; i++ )
|
|
{
|
|
NFM_PVS_SEGMENT_V1 pvs_segment;
|
|
pStream->Read( &pvs_segment, sizeof(pvs_segment) );
|
|
|
|
int nWorldSegmentX = ( m_pHeader->nMapStartPosX*m_pHeader->nSegmentCountPerMap ) + pvs_segment.nSegmentX;
|
|
int nWorldSegmentY = ( m_pHeader->nMapStartPosY*m_pHeader->nSegmentCountPerMap ) + pvs_segment.nSegmentY;
|
|
|
|
SEGMENT_ROOT* pFind = NULL;
|
|
if( m_hashBySEGMENT.lookup( hashPr_SEGMENT::Key(nWorldSegmentX, nWorldSegmentY) ,pFind ) )
|
|
{
|
|
assert(0 && "m_hashBySEGMENT.lookup 이미 존재 함" );
|
|
}
|
|
else
|
|
{
|
|
//로컬->월드로 변경됨
|
|
SEGMENT_ROOT* pSEGMENT_ROOT = new SEGMENT_ROOT;
|
|
pSEGMENT_ROOT->nSegmentX = nWorldSegmentX;
|
|
pSEGMENT_ROOT->nSegmentY = nWorldSegmentY;
|
|
|
|
// _oprint( "Root Segment %d %d\n", nWorldSegmentX, nWorldSegmentY );
|
|
|
|
m_hashBySEGMENT.add( hashPr_SEGMENT::Key(nWorldSegmentX, nWorldSegmentY), pSEGMENT_ROOT );
|
|
|
|
for( int n(0); pvs_segment.nIncludeSegmentCount>n; n++ )
|
|
{
|
|
NFM_SEGMENT_DATA_V1 segment_data;
|
|
pStream->Read( &segment_data, sizeof(segment_data) );
|
|
|
|
int nSegmentX = ( m_pHeader->nMapStartPosX*m_pHeader->nSegmentCountPerMap ) + segment_data.nSegmentX;
|
|
int nSegmentY = ( m_pHeader->nMapStartPosY*m_pHeader->nSegmentCountPerMap ) + segment_data.nSegmentY;
|
|
|
|
SEGMENT_DATA* pDataFind = NULL;
|
|
if( pSEGMENT_ROOT->m_hashBySEGMENT.lookup( hashPr_SEGMENT::Key(nSegmentX, nSegmentY), pDataFind ) )
|
|
{
|
|
assert(0 && "pSEGMENT_ROOT->m_hashBySEGMENT.lookup 이미 존재 함" );
|
|
}
|
|
else
|
|
{
|
|
SEGMENT_DATA* pSEGMENT_DATA = new SEGMENT_DATA;
|
|
pSEGMENT_DATA->nSegmentX = nSegmentX;
|
|
pSEGMENT_DATA->nSegmentY = nSegmentY;
|
|
|
|
pSEGMENT_ROOT->m_hashBySEGMENT.add( hashPr_SEGMENT::Key(nSegmentX, nSegmentY), pSEGMENT_DATA );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for( int i(0); m_pHeader->nPropCount>i; i++ )
|
|
{
|
|
NFM_PVS_PROP_V1 pvs_prop;
|
|
pStream->Read( &pvs_prop, sizeof(pvs_prop) );
|
|
|
|
int nWorldSegmentX = ( m_pHeader->nMapStartPosX*m_pHeader->nSegmentCountPerMap ) + pvs_prop.nSegmentX;
|
|
int nWorldSegmentY = ( m_pHeader->nMapStartPosY*m_pHeader->nSegmentCountPerMap ) + pvs_prop.nSegmentY;
|
|
|
|
PROP_ROOT* pFind = NULL;
|
|
if( m_hashByPROP.lookup( hashPr_SEGMENT::Key( nWorldSegmentX, nWorldSegmentY ), pFind ) )
|
|
{
|
|
assert(0 && "m_hashByPROP.lookup 이미 존재 함" );
|
|
}
|
|
else
|
|
{
|
|
PROP_ROOT* pPROP_ROOT = new PROP_ROOT;
|
|
pPROP_ROOT->nSegmentX = nWorldSegmentX;
|
|
pPROP_ROOT->nSegmentY = nWorldSegmentY;
|
|
|
|
m_hashByPROP.add( hashPr_SEGMENT::Key( nWorldSegmentX, nWorldSegmentY ), pPROP_ROOT );
|
|
|
|
for( int n(0); pvs_prop.nIncludePropCount>n; n++ )
|
|
{
|
|
NFM_PROP_DATA_V1 prop_data;
|
|
pStream->Read( &prop_data, sizeof(prop_data) );
|
|
|
|
PROP_DATA* pDataFind = NULL;
|
|
if( pPROP_ROOT->m_hashByPROP.lookup( hashPr_PROP::Key(prop_data.nSegmentIdx, prop_data.nPropIdx) , pDataFind ) )
|
|
{
|
|
// assert(0 && "pPROP_ROOT->m_hashByPROP.lookup 이미 존재함" );
|
|
_oprint( "pPROP_ROOT->m_hashByPROP.lookup 이미 존재함 %d %d\n", prop_data.nSegmentIdx, prop_data.nPropIdx );
|
|
}
|
|
else
|
|
{
|
|
PROP_DATA* pPROP_DATA = new PROP_DATA;
|
|
pPROP_DATA->nSegmentIdx = prop_data.nSegmentIdx;
|
|
pPROP_DATA->nPropIdx = prop_data.nPropIdx;
|
|
|
|
pPROP_ROOT->m_hashByPROP.add( hashPr_PROP::Key(prop_data.nSegmentIdx, prop_data.nPropIdx), pPROP_DATA );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//World 변환
|
|
m_rcSegment.left = (m_pHeader->nMapStartPosX*m_pHeader->nSegmentCountPerMap) + m_pHeader->nSegmentLeft;
|
|
m_rcSegment.right = (m_pHeader->nMapStartPosX*m_pHeader->nSegmentCountPerMap) + m_pHeader->nSegmentRight;
|
|
|
|
m_rcSegment.top = (m_pHeader->nMapStartPosY*m_pHeader->nSegmentCountPerMap) + m_pHeader->nSegmentTop;
|
|
m_rcSegment.bottom = (m_pHeader->nMapStartPosY*m_pHeader->nSegmentCountPerMap) + m_pHeader->nSegmentBottom;
|
|
|
|
delete pStream;
|
|
}
|
|
|
|
struct _SEG_DATA_
|
|
{
|
|
int nSegX;
|
|
int nSegY;
|
|
int nSelect;
|
|
};
|
|
|
|
struct _PROP_DATA_
|
|
{
|
|
size_t nSegmentIdx;
|
|
size_t nPropIdx;
|
|
int nSelect;
|
|
};
|
|
|
|
struct SegmentCompareFN
|
|
{
|
|
bool operator() ( _SEG_DATA_& pr1, _SEG_DATA_& pr2 )
|
|
{
|
|
if( pr1.nSegX != pr2.nSegX )
|
|
return pr1.nSegX < pr2.nSegX;
|
|
else
|
|
return pr1.nSegY < pr2.nSegY;
|
|
}
|
|
};
|
|
|
|
struct PropCompareFN
|
|
{
|
|
bool operator() ( _PROP_DATA_& pr1, _PROP_DATA_& pr2 )
|
|
{
|
|
if( pr1.nSegmentIdx != pr2.nSegmentIdx )
|
|
return pr1.nSegmentIdx < pr2.nSegmentIdx;
|
|
else
|
|
return pr1.nPropIdx < pr2.nPropIdx;
|
|
}
|
|
};
|
|
|
|
void PVSObject::ExportTxt( int nMode, const char* pFileName, int nRootSegmentX, int nRootSegmentY, std::vector<size_t>& vSegXList, std::vector<size_t>& vSegYList, std::vector<size_t>& vPropIdxList, std::vector<size_t>& vPropNumList )
|
|
{
|
|
if( !m_pHeader ) return;
|
|
|
|
int nWorldX = m_pHeader->nMapStartPosX*m_pHeader->nSegmentCountPerMap;
|
|
int nWorldY = m_pHeader->nMapStartPosY*m_pHeader->nSegmentCountPerMap;
|
|
|
|
std::vector< _SEG_DATA_ > export_seglist;
|
|
std::vector< _PROP_DATA_ > export_proplist;
|
|
|
|
//Segment
|
|
{
|
|
SEGMENT_ROOT* pFind = NULL;
|
|
if( m_hashBySEGMENT.lookup( hashPr_SEGMENT::Key(nRootSegmentX, nRootSegmentY), pFind ) )
|
|
{
|
|
SEGMENT_DATA* pDATA=NULL;
|
|
bool res;
|
|
res = pFind->m_hashBySEGMENT.get_first_value( pDATA );
|
|
while ( res )
|
|
{
|
|
if ( pDATA != NULL )
|
|
{ //로컬 변환 됨
|
|
_SEG_DATA_ data;
|
|
data.nSegX = pDATA->nSegmentX-nWorldX;
|
|
data.nSegY = pDATA->nSegmentY-nWorldY;
|
|
data.nSelect = 0;
|
|
|
|
for( unsigned int i(0); vSegXList.size()>i; i++ )
|
|
{
|
|
if( data.nSegX == vSegXList[i] && data.nSegY == vSegYList[i] )
|
|
{
|
|
data.nSelect = 333; // Selected props
|
|
break;
|
|
}
|
|
}
|
|
|
|
export_seglist.push_back( data );
|
|
}
|
|
res = pFind->m_hashBySEGMENT.get_next_value( pDATA );
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string strMode = "ROOT";
|
|
if( nMode == EXPORT_EXCHANGE )
|
|
strMode = "EXCHANGE";
|
|
else if( nMode == EXPORT_ADD )
|
|
strMode = "ADD";
|
|
else if( nMode == EXPORT_SUBTRACT )
|
|
strMode = "SUBTRACT";
|
|
|
|
_performance_print( "%s : %d %d\n", strMode.c_str(), nRootSegmentX-nWorldX, nRootSegmentY-nWorldY );
|
|
|
|
std::sort( export_seglist.begin(), export_seglist.end(), SegmentCompareFN() );
|
|
for( unsigned int i(0); export_seglist.size()>i; i++ )
|
|
{
|
|
_performance_print( "%d %d %d\n", export_seglist[i].nSegX, export_seglist[i].nSegY, export_seglist[i].nSelect );
|
|
}
|
|
|
|
//Prop
|
|
{
|
|
PROP_ROOT* pFind = NULL;
|
|
if( m_hashByPROP.lookup( hashPr_SEGMENT::Key(nRootSegmentX, nRootSegmentY), pFind ) )
|
|
{
|
|
PROP_DATA* pDATA=NULL;
|
|
bool res;
|
|
res = pFind->m_hashByPROP.get_first_value( pDATA );
|
|
while ( res )
|
|
{
|
|
if ( pDATA != NULL )
|
|
{
|
|
_PROP_DATA_ data;
|
|
data.nSegmentIdx = pDATA->nSegmentIdx;
|
|
data.nPropIdx = pDATA->nPropIdx;
|
|
data.nSelect = 0;
|
|
|
|
for( unsigned int i(0); vPropIdxList.size()>i; i++ )
|
|
{
|
|
if( data.nSegmentIdx == vPropIdxList[i] && data.nPropIdx == vPropNumList[i] )
|
|
{
|
|
data.nSelect = 777; //선택된 프랍들
|
|
break;
|
|
}
|
|
}
|
|
|
|
export_proplist.push_back( data );
|
|
}
|
|
res = pFind->m_hashByPROP.get_next_value( pDATA );
|
|
}
|
|
}
|
|
}
|
|
|
|
std::sort( export_proplist.begin(), export_proplist.end(), PropCompareFN() );
|
|
for( unsigned int i(0); export_proplist.size()>i; i++ )
|
|
_performance_print( "%d %d %d\n", export_proplist[i].nSegmentIdx, export_proplist[i].nPropIdx, export_proplist[i].nSelect );
|
|
|
|
FILE* pF = fopen( pFileName, "wt" );
|
|
if( pF )
|
|
{
|
|
//Header
|
|
fprintf( pF, "%s|%d|%d|\n", strMode.c_str(), nRootSegmentX-nWorldX, nRootSegmentY-nWorldY );
|
|
|
|
//Segment
|
|
for( unsigned int i(0); export_seglist.size()>i; i++ )
|
|
{
|
|
if( export_seglist[i].nSelect != 0 )
|
|
fprintf( pF, "SEG|%d|%d|%d|\n", export_seglist[i].nSegX, export_seglist[i].nSegY, export_seglist[i].nSelect );
|
|
else
|
|
fprintf( pF, "SEG|%d|%d|\n", export_seglist[i].nSegX, export_seglist[i].nSegY );
|
|
}
|
|
|
|
//Prop
|
|
for( unsigned int i(0); export_proplist.size()>i; i++ )
|
|
{
|
|
if( export_proplist[i].nSelect != 0 )
|
|
fprintf( pF, "PROP|%d|%d|%d|\n", export_proplist[i].nSegmentIdx, export_proplist[i].nPropIdx, export_proplist[i].nSelect );
|
|
else
|
|
fprintf( pF, "PROP|%d|%d|\n", export_proplist[i].nSegmentIdx, export_proplist[i].nPropIdx );
|
|
}
|
|
|
|
fclose( pF );
|
|
}
|
|
}
|
|
|
|
bool PVSObject::IsVisibleSegment( int nRootSegmentX, int nRootSegmentY, int nSegmentX, int nSegmentY )
|
|
{
|
|
SEGMENT_ROOT* pFind = NULL;
|
|
if( m_hashBySEGMENT.lookup( hashPr_SEGMENT::Key(nRootSegmentX, nRootSegmentY), pFind ) )
|
|
{
|
|
SEGMENT_DATA* pData = NULL;
|
|
if( pFind->m_hashBySEGMENT.lookup( hashPr_SEGMENT::Key(nSegmentX, nSegmentY), pData ) )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool PVSObject::IsVisibleProp( int nRootSegmentX, int nRootSegmentY, size_t nSegmentIdx, size_t nPropIdx )
|
|
{
|
|
PROP_ROOT* pFind = NULL;
|
|
if( m_hashByPROP.lookup( hashPr_SEGMENT::Key(nRootSegmentX, nRootSegmentY), pFind ) )
|
|
{
|
|
PROP_DATA* pData = NULL;
|
|
if( pFind->m_hashByPROP.lookup( hashPr_PROP::Key(nSegmentIdx, nPropIdx), pData ) )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int PVSObject::GetCountChildSegment( int nRootSegmentX, int nRootSegmentY )
|
|
{
|
|
SEGMENT_ROOT* pFind = NULL;
|
|
if( m_hashBySEGMENT.lookup( hashPr_SEGMENT::Key(nRootSegmentX, nRootSegmentY), pFind ) )
|
|
return (int)pFind->m_hashBySEGMENT.size();
|
|
else
|
|
return -1; //데이타 없음
|
|
|
|
return -2;
|
|
}
|
|
|
|
int PVSObject::GetCountChildProp( int nRootSegmentX, int nRootSegmentY )
|
|
{
|
|
PROP_ROOT* pFind = NULL;
|
|
if( m_hashByPROP.lookup( hashPr_SEGMENT::Key(nRootSegmentX, nRootSegmentY), pFind ) )
|
|
return (int)pFind->m_hashByPROP.size();
|
|
else
|
|
return -1; //데이타 없음
|
|
|
|
return -2;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//PVSObjectManager
|
|
|
|
bool PVSObjectManager::m_sToggleAct = true;
|
|
|
|
PVSObjectManager::PVSObjectManager()
|
|
{
|
|
m_pCurPVSObject = NULL;
|
|
m_bIsPVSActive = false;
|
|
}
|
|
|
|
PVSObjectManager::~PVSObjectManager()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
//현재 위치 설정
|
|
void PVSObjectManager::SetRootSegment( int nSegmentX, int nSegmentY )
|
|
{
|
|
m_nRootSegmentX = nSegmentX;
|
|
m_nRootSegmentY = nSegmentY;
|
|
|
|
if( m_pCurPVSObject )
|
|
m_bIsPVSActive = m_pCurPVSObject->IsPVSActCheck( nSegmentX, nSegmentY );
|
|
else
|
|
m_bIsPVSActive = false;
|
|
}
|
|
|
|
bool PVSObjectManager::IsPVSActive()
|
|
{
|
|
if( m_sToggleAct == false ) return false;
|
|
|
|
return m_bIsPVSActive;
|
|
}
|
|
|
|
bool PVSObjectManager::CheckSegment( int nSegmentX, int nSegmentY )
|
|
{
|
|
if( m_pCurPVSObject )
|
|
{
|
|
return m_pCurPVSObject->IsVisibleSegment( m_nRootSegmentX, m_nRootSegmentY, nSegmentX, nSegmentY );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool PVSObjectManager::CheckProp( size_t nSegmentIdx, size_t nPropIdx )
|
|
{
|
|
if( m_pCurPVSObject )
|
|
{
|
|
return m_pCurPVSObject->IsVisibleProp( m_nRootSegmentX, m_nRootSegmentY, nSegmentIdx, nPropIdx );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void PVSObjectManager::convertWorldToMapPos(int worldPosX, int worldPosY, int& mapX, int& mapY)
|
|
{
|
|
mapX = worldPosX/16128;
|
|
mapY = worldPosY/16128;
|
|
}
|
|
|
|
//Load
|
|
//Warp Loading ex) 던전
|
|
void PVSObjectManager::WarpLoad( int nWorldPosX, int nWorldPosY )
|
|
{
|
|
int nStartMapX = nWorldPosX/16128;
|
|
int nStartMapY = nWorldPosY/16128;
|
|
|
|
//이미 로딩 되어 있는가?
|
|
for( unsigned int i(0); m_vPVSObjectList.size()>i; i++ )
|
|
{
|
|
if( m_vPVSObjectList[i]->IsMapCheck( nStartMapX, nStartMapY ) )
|
|
return;
|
|
}
|
|
|
|
//새로 로딩
|
|
std::string strFileName;
|
|
XStringUtil::Format( strFileName, "m%03d_%03d.pvs", nStartMapX, nStartMapY );
|
|
|
|
if( !KFileManager::Instance().IsValidResource( strFileName.c_str() ) )
|
|
return;
|
|
|
|
PVSObject* pPVSObject = new PVSObject;
|
|
pPVSObject->Load( strFileName.c_str() );
|
|
|
|
m_vPVSObjectList.push_back( pPVSObject );
|
|
|
|
m_pCurPVSObject = pPVSObject;
|
|
}
|
|
|
|
//Thread Loading ex) 마을
|
|
void PVSObjectManager::ThreadLoad( int nWorldPosX, int nWorldPosY )
|
|
{
|
|
|
|
}
|
|
|
|
void PVSObjectManager::Clear()
|
|
{
|
|
m_pCurPVSObject = NULL;
|
|
SAFE_DELETE_VECTOR( m_vPVSObjectList );
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//PVS Merge
|
|
PVSMerge::PVSMerge()
|
|
{
|
|
|
|
}
|
|
|
|
PVSMerge::~PVSMerge()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void PVSMerge::Init()
|
|
{
|
|
memset( &m_Mainheader, 0, sizeof(m_Mainheader) );
|
|
|
|
Clear();
|
|
}
|
|
|
|
void PVSMerge::Clear()
|
|
{
|
|
for( unsigned int i(0); m_vMergeSegment.size()>i; i++ )
|
|
{
|
|
delete m_vMergeSegment[i]->pSegment;
|
|
|
|
for( unsigned int n(0); m_vMergeSegment[i]->vSegmentList.size()>n; n++ )
|
|
{
|
|
delete m_vMergeSegment[i]->vSegmentList[n];
|
|
}
|
|
m_vMergeSegment[i]->vSegmentList.clear();
|
|
|
|
delete m_vMergeSegment[i];
|
|
}
|
|
m_vMergeSegment.clear();
|
|
|
|
for( unsigned int i(0); m_vMergeProp.size()>i; i++ )
|
|
{
|
|
delete m_vMergeProp[i]->pProp;
|
|
|
|
for( unsigned int n(0); m_vMergeProp[i]->vPropList.size()>n; n++ )
|
|
{
|
|
delete m_vMergeProp[i]->vPropList[n];
|
|
}
|
|
m_vMergeProp[i]->vPropList.clear();
|
|
|
|
delete m_vMergeProp[i];
|
|
}
|
|
m_vMergeProp.clear();
|
|
}
|
|
|
|
unsigned int PVSMerge::MergeSegment( std::vector< MERGE_SEGMENT* >& main_list, struct NFM_PVS_SEGMENT_V1* pMergeSegment, std::vector<NFM_SEGMENT_DATA_V1>& segment_list )
|
|
{
|
|
bool bCheckSegment;
|
|
for( unsigned int i(0); main_list.size()>i; i++ )
|
|
{
|
|
//기존에 존재하는 세그먼트
|
|
if( main_list[i]->pSegment->nSegmentX == pMergeSegment->nSegmentX &&
|
|
main_list[i]->pSegment->nSegmentY == pMergeSegment->nSegmentY )
|
|
{
|
|
for( unsigned int n(0); segment_list.size()>n; n++ )
|
|
{
|
|
bCheckSegment = false;
|
|
for( unsigned int j(0); main_list[i]->vSegmentList.size()>j; j++ )
|
|
{
|
|
if( segment_list[n].nSegmentX == main_list[i]->vSegmentList[j]->nSegmentX &&
|
|
segment_list[n].nSegmentY == main_list[i]->vSegmentList[j]->nSegmentY )
|
|
{ //이미 포함
|
|
bCheckSegment = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( !bCheckSegment )
|
|
{ //새로 추가 되는 세그먼트 데이타
|
|
NFM_SEGMENT_DATA_V1* pData = new NFM_SEGMENT_DATA_V1;
|
|
pData->nSegmentX = segment_list[n].nSegmentX;
|
|
pData->nSegmentY = segment_list[n].nSegmentY;
|
|
main_list[i]->vSegmentList.push_back( pData );
|
|
}
|
|
}
|
|
|
|
//세그먼트 수 변경
|
|
main_list[i]->pSegment->nIncludeSegmentCount += main_list[i]->vSegmentList.size();
|
|
return main_list.size();
|
|
}
|
|
}
|
|
|
|
//새로 추가 되는 것, 모두 포함
|
|
MERGE_SEGMENT* pNewMergeSegment = new MERGE_SEGMENT;
|
|
pNewMergeSegment->pSegment = new NFM_PVS_SEGMENT_V1;
|
|
|
|
pNewMergeSegment->pSegment->nSegmentX = pMergeSegment->nSegmentX;
|
|
pNewMergeSegment->pSegment->nSegmentY = pMergeSegment->nSegmentY;
|
|
pNewMergeSegment->pSegment->nIncludeSegmentCount = pMergeSegment->nIncludeSegmentCount;
|
|
|
|
for( unsigned int i(0); segment_list.size()>i; i++ )
|
|
{
|
|
NFM_SEGMENT_DATA_V1* pData = new NFM_SEGMENT_DATA_V1;
|
|
pData->nSegmentX = segment_list[i].nSegmentX;
|
|
pData->nSegmentY = segment_list[i].nSegmentY;
|
|
|
|
pNewMergeSegment->vSegmentList.push_back( pData );
|
|
}
|
|
|
|
assert( pNewMergeSegment->pSegment->nIncludeSegmentCount == pNewMergeSegment->vSegmentList.size() );
|
|
|
|
main_list.push_back( pNewMergeSegment );
|
|
|
|
return main_list.size();
|
|
}
|
|
|
|
unsigned int PVSMerge::MergeProp( std::vector< MERGE_PROP* >& main_list, struct NFM_PVS_PROP_V1* pMergeProp, std::vector<NFM_PROP_DATA_V1>& prop_list )
|
|
{
|
|
bool bCheckProp = false;
|
|
for( unsigned int i(0); main_list.size()>i; i++ )
|
|
{
|
|
//기존에 존재하는 프랍
|
|
if( main_list[i]->pProp->nSegmentX == pMergeProp->nSegmentX &&
|
|
main_list[i]->pProp->nSegmentY == pMergeProp->nSegmentY )
|
|
{
|
|
for( unsigned int n(0); prop_list.size()>n; n++ )
|
|
{
|
|
bCheckProp = false;
|
|
for( unsigned int j(0); main_list[i]->vPropList.size()>j; j++ )
|
|
{
|
|
if( prop_list[n].nSegmentIdx == main_list[i]->vPropList[j]->nSegmentIdx &&
|
|
prop_list[n].nPropIdx == main_list[i]->vPropList[j]->nPropIdx )
|
|
{ //이미 포함
|
|
bCheckProp = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( !bCheckProp )
|
|
{ //새로 추가 되는 세그먼트 데이타
|
|
NFM_PROP_DATA_V1* pData = new NFM_PROP_DATA_V1;
|
|
pData->nSegmentIdx = prop_list[n].nSegmentIdx;
|
|
pData->nPropIdx = prop_list[n].nPropIdx ;
|
|
main_list[i]->vPropList.push_back( pData );
|
|
}
|
|
}
|
|
|
|
//세그먼트 수 변경
|
|
main_list[i]->pProp->nIncludePropCount += main_list[i]->vPropList.size();
|
|
return main_list.size();
|
|
}
|
|
}
|
|
|
|
//새로 추가 되는 프랍
|
|
MERGE_PROP* pNewMergeProp = new MERGE_PROP;
|
|
|
|
pNewMergeProp->pProp = new NFM_PVS_PROP_V1;
|
|
pNewMergeProp->pProp->nSegmentX = pMergeProp->nSegmentX;
|
|
pNewMergeProp->pProp->nSegmentY = pMergeProp->nSegmentY;
|
|
pNewMergeProp->pProp->nIncludePropCount = pMergeProp->nIncludePropCount;
|
|
|
|
for( unsigned int i(0); prop_list.size()>i; i++ )
|
|
{
|
|
NFM_PROP_DATA_V1* pData = new NFM_PROP_DATA_V1;
|
|
pData->nSegmentIdx = prop_list[i].nSegmentIdx;
|
|
pData->nPropIdx = prop_list[i].nPropIdx ;
|
|
|
|
pNewMergeProp->vPropList.push_back( pData );
|
|
}
|
|
|
|
assert( pNewMergeProp->pProp->nIncludePropCount == pNewMergeProp->vPropList.size() );
|
|
|
|
main_list.push_back( pNewMergeProp );
|
|
|
|
return main_list.size();
|
|
}
|
|
|
|
void PVSMerge::MergeFile( const char * pFileName )
|
|
{
|
|
KStream* pStream = new KFileStream( pFileName );
|
|
if( NULL == pStream || !pStream->IsValid() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
NFM_PVS_HEADER_V1 header;
|
|
pStream->Read( &header, sizeof(header) );
|
|
|
|
if( m_Mainheader.dwVersion == 0 )
|
|
{ //처음 값
|
|
strcpy_s( m_Mainheader.szSign, NFM_PVS_FILE_SIGN );
|
|
m_Mainheader.dwVersion = header.dwVersion;
|
|
m_Mainheader.nSegmentCountPerMap = header.nSegmentCountPerMap;
|
|
m_Mainheader.nMapStartPosX = header.nMapStartPosX;
|
|
m_Mainheader.nMapStartPosY = header.nMapStartPosY;
|
|
|
|
m_Mainheader.nSegmentLeft = header.nSegmentLeft ;
|
|
m_Mainheader.nSegmentTop = header.nSegmentTop ;
|
|
m_Mainheader.nSegmentRight = header.nSegmentRight ;
|
|
m_Mainheader.nSegmentBottom = header.nSegmentBottom;
|
|
}
|
|
|
|
//가장 크게 설정
|
|
if( m_Mainheader.nSegmentLeft > header.nSegmentLeft )
|
|
m_Mainheader.nSegmentLeft = header.nSegmentLeft;
|
|
|
|
if( m_Mainheader.nSegmentTop > header.nSegmentTop )
|
|
m_Mainheader.nSegmentTop = header.nSegmentTop;
|
|
|
|
if( m_Mainheader.nSegmentRight < header.nSegmentRight )
|
|
m_Mainheader.nSegmentRight = header.nSegmentRight;
|
|
|
|
if( m_Mainheader.nSegmentBottom < header.nSegmentBottom )
|
|
m_Mainheader.nSegmentBottom = header.nSegmentBottom;
|
|
|
|
for( int i(0); header.nSegmentCount>i; i++ )
|
|
{
|
|
NFM_PVS_SEGMENT_V1 pvs_segment;
|
|
pStream->Read( &pvs_segment, sizeof(pvs_segment) );
|
|
|
|
std::vector<NFM_SEGMENT_DATA_V1> segment_list;
|
|
for( int n(0); pvs_segment.nIncludeSegmentCount>n; n++ )
|
|
{
|
|
NFM_SEGMENT_DATA_V1 segment_data;
|
|
pStream->Read( &segment_data, sizeof(segment_data) );
|
|
|
|
segment_list.push_back( segment_data );
|
|
}
|
|
|
|
MergeSegment( m_vMergeSegment, &pvs_segment, segment_list );
|
|
}
|
|
|
|
for( int i(0); header.nPropCount>i; i++ )
|
|
{
|
|
NFM_PVS_PROP_V1 pvs_prop;
|
|
pStream->Read( &pvs_prop, sizeof(pvs_prop) );
|
|
|
|
std::vector<NFM_PROP_DATA_V1> prop_list;
|
|
|
|
for( int n(0); pvs_prop.nIncludePropCount>n; n++ )
|
|
{
|
|
NFM_PROP_DATA_V1 prop_data;
|
|
pStream->Read( &prop_data, sizeof(prop_data) );
|
|
|
|
prop_list.push_back( prop_data );
|
|
}
|
|
|
|
MergeProp( m_vMergeProp, &pvs_prop, prop_list );
|
|
}
|
|
|
|
m_Mainheader.nSegmentCount = m_vMergeSegment.size();
|
|
m_Mainheader.nPropCount = m_vMergeProp.size();
|
|
|
|
delete pStream;
|
|
}
|
|
|
|
bool IsExistSegment( std::vector<struct NFM_SEGMENT_DATA_V1*>& seglist, const int& nSegX, const int& nSegY )
|
|
{
|
|
for( unsigned int i(0); seglist.size()>i; i++ )
|
|
{
|
|
NFM_SEGMENT_DATA_V1* pData = seglist[i];
|
|
if( pData->nSegmentX == nSegX && pData->nSegmentY == nSegY )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool IsExistProp( std::vector<struct NFM_PROP_DATA_V1*>& proplist, const size_t& nSegmentIdx, const size_t& nPropIdx )
|
|
{
|
|
for( unsigned int i(0); proplist.size()>i; i++ )
|
|
{
|
|
NFM_PROP_DATA_V1* pData = proplist[i];
|
|
if( pData->nSegmentIdx == nSegmentIdx && pData->nPropIdx == nPropIdx )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void SubTracrtSegment( std::vector<struct NFM_SEGMENT_DATA_V1*>& seglist, const int& nSegX, const int& nSegY )
|
|
{
|
|
for( unsigned int i(0); seglist.size()>i; i++ )
|
|
{
|
|
NFM_SEGMENT_DATA_V1* pData = seglist[i];
|
|
if( pData->nSegmentX == nSegX && pData->nSegmentY == nSegY )
|
|
{
|
|
delete pData;
|
|
seglist.erase( seglist.begin()+i );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SubTracrtProp( std::vector<struct NFM_PROP_DATA_V1*>& proplist, const size_t& nSegmentIdx, const size_t& nPropIdx )
|
|
{
|
|
for( unsigned int i(0); proplist.size()>i; i++ )
|
|
{
|
|
NFM_PROP_DATA_V1* pData = proplist[i];
|
|
if( pData->nSegmentIdx == nSegmentIdx && pData->nPropIdx == nPropIdx )
|
|
{
|
|
delete pData;
|
|
proplist.erase( proplist.begin()+i );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
PVSMerge::MERGE_SEGMENT* FindMergeSegment( int nRootX, int nRootY, std::vector< PVSMerge::MERGE_SEGMENT* >& merge_seg_list )
|
|
{
|
|
for( unsigned int i(0); merge_seg_list.size()>i; i++ )
|
|
{
|
|
PVSMerge::MERGE_SEGMENT* pMergeSeg = merge_seg_list[i];
|
|
if( pMergeSeg->pSegment->nSegmentX == nRootX && pMergeSeg->pSegment->nSegmentY == nRootY )
|
|
{
|
|
return pMergeSeg;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
PVSMerge::MERGE_PROP* FindMergeProp( int nRootX, int nRootY, std::vector< PVSMerge::MERGE_PROP* >& merge_prop_list )
|
|
{
|
|
for( unsigned int i(0); merge_prop_list.size()>i; i++ )
|
|
{
|
|
PVSMerge::MERGE_PROP* pMergeProp = merge_prop_list[i];
|
|
if( pMergeProp->pProp->nSegmentX == nRootX && pMergeProp->pProp->nSegmentY == nRootY )
|
|
{
|
|
return pMergeProp;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void _add_segment_pvs( int nRootX, int nRootY, std::vector< PVSMerge::MERGE_SEGMENT* >& merge_seg_list, std::vector< _SEG_DATA_ >& seglist )
|
|
{
|
|
int nSegX = -1;
|
|
int nSegY = -1;
|
|
|
|
PVSMerge::MERGE_SEGMENT* pMergeSeg = FindMergeSegment( nRootX, nRootY, merge_seg_list );
|
|
if( pMergeSeg )
|
|
{
|
|
for( unsigned int j(0); seglist.size()>j; j++ )
|
|
{
|
|
nSegX = seglist[j].nSegX;
|
|
nSegY = seglist[j].nSegY;
|
|
|
|
if( !IsExistSegment( pMergeSeg->vSegmentList, nSegX, nSegY ) )
|
|
{
|
|
//추가
|
|
NFM_SEGMENT_DATA_V1* pNewSeg = new NFM_SEGMENT_DATA_V1;
|
|
pNewSeg->nSegmentX = nSegX;
|
|
pNewSeg->nSegmentY = nSegY;
|
|
|
|
pMergeSeg->vSegmentList.push_back( pNewSeg );
|
|
}
|
|
}
|
|
//갯수 수정
|
|
pMergeSeg->pSegment->nIncludeSegmentCount = pMergeSeg->vSegmentList.size();
|
|
}
|
|
}
|
|
|
|
void _add_prop_pvs( int nRootX, int nRootY, std::vector< PVSMerge::MERGE_PROP* >& merge_prop_list, std::vector< _PROP_DATA_ >& proplist )
|
|
{
|
|
size_t nSegmentIdx;
|
|
size_t nPropIdx;
|
|
|
|
PVSMerge::MERGE_PROP* pMergeProp = FindMergeProp( nRootX, nRootY, merge_prop_list );
|
|
if( pMergeProp )
|
|
{
|
|
for( unsigned int j(0); proplist.size()>j; j++ )
|
|
{
|
|
nSegmentIdx = proplist[j].nSegmentIdx;
|
|
nPropIdx = proplist[j].nPropIdx;
|
|
|
|
if( !IsExistProp( pMergeProp->vPropList, nSegmentIdx, nPropIdx ) )
|
|
{
|
|
//추가
|
|
NFM_PROP_DATA_V1* pNewProp = new NFM_PROP_DATA_V1;
|
|
pNewProp->nSegmentIdx = nSegmentIdx;
|
|
pNewProp->nPropIdx = nPropIdx;
|
|
|
|
pMergeProp->vPropList.push_back( pNewProp );
|
|
}
|
|
}
|
|
//갯수 수정
|
|
pMergeProp->pProp->nIncludePropCount = pMergeProp->vPropList.size();
|
|
return;
|
|
}
|
|
}
|
|
|
|
void _subtract_segment_pvs( int nRootX, int nRootY, std::vector< PVSMerge::MERGE_SEGMENT* >& merge_seg_list, std::vector< _SEG_DATA_ >& seglist )
|
|
{
|
|
int nSegX = -1;
|
|
int nSegY = -1;
|
|
|
|
PVSMerge::MERGE_SEGMENT* pMergeSeg = FindMergeSegment( nRootX, nRootY, merge_seg_list );
|
|
if( pMergeSeg )
|
|
{
|
|
for( unsigned int j(0); seglist.size()>j; j++ )
|
|
{
|
|
nSegX = seglist[j].nSegX;
|
|
nSegY = seglist[j].nSegY;
|
|
SubTracrtSegment( pMergeSeg->vSegmentList, nSegX, nSegY );
|
|
}
|
|
//갯수 수정
|
|
pMergeSeg->pSegment->nIncludeSegmentCount = pMergeSeg->vSegmentList.size();
|
|
}
|
|
}
|
|
|
|
void _subtract_prop_pvs( int nRootX, int nRootY, std::vector< PVSMerge::MERGE_PROP* >& merge_prop_list, std::vector< _PROP_DATA_ >& proplist )
|
|
{
|
|
size_t nSegmentIdx;
|
|
size_t nPropIdx;
|
|
|
|
PVSMerge::MERGE_PROP* pMergeProp = FindMergeProp( nRootX, nRootY, merge_prop_list );
|
|
if( pMergeProp )
|
|
{
|
|
for( unsigned int j(0); proplist.size()>j; j++ )
|
|
{
|
|
nSegmentIdx = proplist[j].nSegmentIdx;
|
|
nPropIdx = proplist[j].nPropIdx;
|
|
SubTracrtProp( pMergeProp->vPropList, nSegmentIdx, nPropIdx );
|
|
}
|
|
//갯수 수정
|
|
pMergeProp->pProp->nIncludePropCount = pMergeProp->vPropList.size();
|
|
}
|
|
}
|
|
|
|
void _exchange_segment_pvs( int nRootX, int nRootY, std::vector< PVSMerge::MERGE_SEGMENT* >& merge_seg_list, std::vector< _SEG_DATA_ >& seglist )
|
|
{
|
|
PVSMerge::MERGE_SEGMENT* pMergeSeg = FindMergeSegment( nRootX, nRootY, merge_seg_list );
|
|
if( pMergeSeg )
|
|
{
|
|
SAFE_DELETE_VECTOR( pMergeSeg->vSegmentList );
|
|
|
|
for( unsigned int j(0); seglist.size()>j; j++ )
|
|
{
|
|
//추가
|
|
NFM_SEGMENT_DATA_V1* pNewSeg = new NFM_SEGMENT_DATA_V1;
|
|
pNewSeg->nSegmentX = seglist[j].nSegX;
|
|
pNewSeg->nSegmentY = seglist[j].nSegY;
|
|
|
|
pMergeSeg->vSegmentList.push_back( pNewSeg );
|
|
}
|
|
|
|
pMergeSeg->pSegment->nIncludeSegmentCount = pMergeSeg->vSegmentList.size();
|
|
}
|
|
}
|
|
void _exchange_prop_pvs( int nRootX, int nRootY, std::vector< PVSMerge::MERGE_PROP* >& merge_prop_list, std::vector< _PROP_DATA_ >& proplist )
|
|
{
|
|
PVSMerge::MERGE_PROP* pMergeProp = FindMergeProp( nRootX, nRootY, merge_prop_list );
|
|
if( pMergeProp )
|
|
{
|
|
SAFE_DELETE_VECTOR( pMergeProp->vPropList );
|
|
|
|
for( unsigned int j(0); proplist.size()>j; j++ )
|
|
{
|
|
//추가
|
|
NFM_PROP_DATA_V1* pNewProp = new NFM_PROP_DATA_V1;
|
|
pNewProp->nSegmentIdx = proplist[j].nSegmentIdx;
|
|
pNewProp->nPropIdx = proplist[j].nPropIdx;
|
|
|
|
pMergeProp->vPropList.push_back( pNewProp );
|
|
}
|
|
|
|
pMergeProp->pProp->nIncludePropCount = pMergeProp->vPropList.size();
|
|
}
|
|
}
|
|
|
|
//Modify
|
|
void PVSMerge::Modify( const char * pFileName )
|
|
{
|
|
KStream* pStream = new KFileStream( pFileName );
|
|
if( NULL == pStream )
|
|
{
|
|
return;
|
|
}
|
|
|
|
size_t nLen = pStream->GetLength();
|
|
char * pstrTemp = new char[nLen+1];
|
|
pstrTemp[nLen] = '\0';
|
|
for( size_t i(0); nLen>i; i++ )
|
|
{
|
|
pStream->Read( &pstrTemp[i], 1 );
|
|
}
|
|
|
|
std::vector< std::string > vString;
|
|
XStringUtil::Split( pstrTemp, vString, "|\r\n" );
|
|
|
|
int nLoop = (int)vString.size()/3;
|
|
int n=0;
|
|
|
|
std::string strCommand;
|
|
int nRootX, nRootY;
|
|
|
|
std::vector< _SEG_DATA_ > seglist;
|
|
std::vector< _PROP_DATA_ > proplist;
|
|
|
|
for( int i(0); nLoop>i; i++ )
|
|
{
|
|
std::string strData = vString[n++].c_str();
|
|
int nX = atoi( vString[n++].c_str() );
|
|
int nY = atoi( vString[n++].c_str() );
|
|
|
|
if( i==0 )
|
|
{
|
|
strCommand = strData;
|
|
nRootX = nX;
|
|
nRootY = nY;
|
|
}
|
|
else
|
|
{
|
|
if( !stricmp( strData.c_str(), "SEG" ) )
|
|
{
|
|
_SEG_DATA_ data;
|
|
data.nSegX = nX;
|
|
data.nSegY = nY;
|
|
seglist.push_back( data );
|
|
}
|
|
else if( !stricmp( strData.c_str(), "PROP" ) )
|
|
{
|
|
_PROP_DATA_ data;
|
|
data.nSegmentIdx = nX;
|
|
data.nPropIdx = nY;
|
|
proplist.push_back( data );
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !stricmp( strCommand.c_str(), "ADD") )
|
|
{
|
|
_add_segment_pvs( nRootX, nRootY, m_vMergeSegment, seglist );
|
|
_add_prop_pvs( nRootX, nRootY, m_vMergeProp, proplist );
|
|
}
|
|
else if( !stricmp( strCommand.c_str(), "SUBTRACT") )
|
|
{
|
|
_subtract_segment_pvs( nRootX, nRootY, m_vMergeSegment, seglist );
|
|
_subtract_prop_pvs( nRootX, nRootY, m_vMergeProp, proplist );
|
|
}
|
|
else if( !stricmp( strCommand.c_str(), "EXCHANGE") )
|
|
{
|
|
_exchange_segment_pvs( nRootX, nRootY, m_vMergeSegment, seglist );
|
|
_exchange_prop_pvs( nRootX, nRootY, m_vMergeProp, proplist );
|
|
}
|
|
|
|
delete [] pstrTemp;
|
|
delete pStream;
|
|
}
|
|
|
|
void PVSMerge::SaveMerge( const char * pFileName )
|
|
{
|
|
FILE* pF = fopen( pFileName, "wb" );
|
|
if( pF == NULL ) return;
|
|
|
|
NFM_PVS_HEADER_V1 header;
|
|
memcpy( &header, &m_Mainheader, sizeof(header) );
|
|
|
|
fwrite( &header, sizeof(header), 1, pF );
|
|
|
|
for( unsigned int i(0); m_vMergeSegment.size()>i; i++ )
|
|
{
|
|
NFM_PVS_SEGMENT_V1 pvs_segment;
|
|
pvs_segment.nSegmentX = m_vMergeSegment[i]->pSegment->nSegmentX;
|
|
pvs_segment.nSegmentY = m_vMergeSegment[i]->pSegment->nSegmentY;
|
|
pvs_segment.nIncludeSegmentCount = m_vMergeSegment[i]->vSegmentList.size();
|
|
|
|
int nWorldSegmentX = (header.nMapStartPosX*header.nSegmentCountPerMap)+pvs_segment.nSegmentX;
|
|
int nWorldSegmentY = (header.nMapStartPosY*header.nSegmentCountPerMap)+pvs_segment.nSegmentY;
|
|
|
|
// _oprint( "Segment Index : W[%d %d] - L[%d %d]\n", nWorldSegmentX, nWorldSegmentY, pvs_segment.nSegmentX, pvs_segment.nSegmentY );
|
|
|
|
fwrite( &pvs_segment, sizeof(pvs_segment), 1, pF );
|
|
|
|
for( int n(0); pvs_segment.nIncludeSegmentCount>n; n++ )
|
|
{
|
|
NFM_SEGMENT_DATA_V1 segment_data;
|
|
segment_data.nSegmentX = m_vMergeSegment[i]->vSegmentList[n]->nSegmentX;
|
|
segment_data.nSegmentY = m_vMergeSegment[i]->vSegmentList[n]->nSegmentY;
|
|
|
|
// _oprint( "Segment Index : %d %d\n", segment_data.nSegmentX, segment_data.nSegmentY );
|
|
|
|
fwrite( &segment_data, sizeof(segment_data), 1, pF );
|
|
}
|
|
}
|
|
|
|
for( unsigned int i(0); m_vMergeProp.size()>i; i++ )
|
|
{
|
|
NFM_PVS_PROP_V1 pvs_prop;
|
|
|
|
pvs_prop.nSegmentX = m_vMergeProp[i]->pProp->nSegmentX;
|
|
pvs_prop.nSegmentY = m_vMergeProp[i]->pProp->nSegmentY;
|
|
pvs_prop.nIncludePropCount = m_vMergeProp[i]->vPropList.size();
|
|
|
|
// _oprint( "Segment Index : %d %d\n", pvs_prop.nSegmentX, pvs_prop.nSegmentY );
|
|
|
|
fwrite( &pvs_prop, sizeof(pvs_prop), 1, pF );
|
|
|
|
for( int n(0); pvs_prop.nIncludePropCount>n; n++ )
|
|
{
|
|
NFM_PROP_DATA_V1 prop_data;
|
|
prop_data.nSegmentIdx = m_vMergeProp[i]->vPropList[n]->nSegmentIdx;
|
|
prop_data.nPropIdx = m_vMergeProp[i]->vPropList[n]->nPropIdx;
|
|
|
|
fwrite( &prop_data, sizeof(prop_data), 1, pF );
|
|
}
|
|
}
|
|
|
|
fclose( pF );
|
|
}
|