299 lines
5.8 KiB
C++
299 lines
5.8 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, SH Software Co. Ltd.
|
|
// = FileName : XRegionSide 类
|
|
// = Version : ver2.0
|
|
// = Author : zjq
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: XRegionSide 定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "XRegionSide.h"
|
|
#include "XSideVector.h"
|
|
#include "XSortSideOnVertex.h"
|
|
#include "XRegion.h"
|
|
|
|
DList<XRegionSide> * XRegionSide::g_pAllWalls = NULL;
|
|
XRegion * XRegionSide::g_pCurRegion = NULL;
|
|
static XRegionSide *g_pMarkSide = NULL;
|
|
|
|
static int CompareSide(const XSideVector *p1, const void *p2)
|
|
{
|
|
const XRegionSide *pSide = (const XRegionSide *)p2;
|
|
return (p1->m_pSide == pSide) ? 0 : 1;
|
|
}
|
|
|
|
XRegionSide::XRegionSide()
|
|
: m_pLeftRegion(NULL), m_pRightRegion(NULL)
|
|
{
|
|
m_pStartNode = m_pEndNode = NULL;
|
|
m_nCurSide = 0;
|
|
m_bBadSide = 0;
|
|
}
|
|
|
|
XRegionSide::XRegionSide(const XCurveSegment &seg)
|
|
: XCurveSegment(seg), m_pLeftRegion(NULL), m_pRightRegion(NULL)
|
|
{
|
|
m_pStartNode = m_pEndNode = NULL;
|
|
m_nCurSide = 0;
|
|
m_bBadSide = 0;
|
|
}
|
|
|
|
XRegionSide::~XRegionSide()
|
|
{
|
|
}
|
|
|
|
// 功能: 搜索房间
|
|
// 参数:
|
|
// pSpt--当前向量的起点为, nSide--以pSpt为起点的相对左(0)右(1)
|
|
// 返回: RTNORM--找到一房间; RTERROR--当前墙不构成封闭域; RTNONE--第一个墙不封闭
|
|
// 注意: 当前已经进栈(Top==Tail())
|
|
// 考虑了墙体标高
|
|
int XRegionSide::Trival(XSortSideOnVertex *pSpt, int nSide)
|
|
{
|
|
ASSERT(pSpt);
|
|
if (!XRegionSide::g_pCurRegion)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
XRegion &aRegion = *g_pCurRegion;
|
|
if (ads_usrbrk())
|
|
{
|
|
g_pMarkSide = NULL;
|
|
return RTCAN;
|
|
}
|
|
|
|
int nCurSide;
|
|
XSortSideOnVertex *pNextPt;
|
|
if (pSpt == m_pStartNode)
|
|
{
|
|
pNextPt = m_pEndNode;
|
|
nCurSide = nSide;
|
|
}
|
|
else
|
|
{
|
|
pNextPt = m_pStartNode;
|
|
nCurSide = !nSide;
|
|
}
|
|
|
|
m_nCurSide = nCurSide; //实际 nSide, Find Absolute nCurSide
|
|
|
|
XSortSideOnVertex *pWallsOnPt = pNextPt;
|
|
if (!pWallsOnPt)
|
|
{
|
|
ASSERT(0);
|
|
return RTERROR;
|
|
}
|
|
|
|
XSortSideOnVertex &sortSides = *pWallsOnPt;
|
|
int nLength = sortSides.Length();
|
|
|
|
XSideVector *pVector = sortSides.FindNode(this, CompareSide);
|
|
if (!pVector)
|
|
{
|
|
ASSERT(0);
|
|
return RTERROR;
|
|
}
|
|
|
|
int nPos = sortSides.CurPosition();
|
|
int nLen = nLength;
|
|
int nRetFlg = RTERROR;
|
|
|
|
if (nSide == 1) //右侧,查找相对最左边的
|
|
{
|
|
for (int i = 1; i < nLen; i++) //查找最左边的有效墙
|
|
{
|
|
int nIndex = i + nPos;
|
|
if (nIndex >= nLen)
|
|
{
|
|
nIndex -= nLen;
|
|
}
|
|
|
|
XRegionSide *pNextWall = (XRegionSide *)(sortSides[nIndex]->m_pSide);
|
|
if (!pNextWall)
|
|
{
|
|
continue;
|
|
}
|
|
else if (pNextWall == aRegion.Head())
|
|
{
|
|
if (pNextPt == aRegion.Head()->GetStartNode())
|
|
{
|
|
return RTNORM; // 找到一房间
|
|
}
|
|
else
|
|
{
|
|
ASSERT(g_pMarkSide == NULL);
|
|
g_pMarkSide=pNextWall; //回退到标记
|
|
pNextWall->SetBadSide(1);
|
|
return RTNONE;
|
|
}
|
|
}
|
|
else if (aRegion.Exist(pNextWall))
|
|
{
|
|
ASSERT(g_pMarkSide == NULL);
|
|
g_pMarkSide = pNextWall; //回退到标记
|
|
pNextWall->SetBadSide(1);
|
|
return RTNONE; // Z Modify here on 2001/12/28
|
|
}
|
|
|
|
aRegion.Push(pNextWall);
|
|
nRetFlg = pNextWall->Trival(pNextPt, nSide);
|
|
if (nRetFlg == RTNORM)
|
|
{
|
|
return RTNORM;
|
|
}
|
|
|
|
aRegion.Pop();
|
|
if (nRetFlg == RTNONE)
|
|
{
|
|
//回退到标记
|
|
if (aRegion.Tail()!=g_pMarkSide)
|
|
{
|
|
return RTNONE;
|
|
}
|
|
|
|
g_pMarkSide = NULL; //已经到标记
|
|
return RTERROR;
|
|
}
|
|
else if (nRetFlg == RTCAN)
|
|
{
|
|
return nRetFlg;
|
|
}
|
|
else if (nRetFlg == RTERROR)
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|
|
else // 左侧,查找相对最右边的
|
|
{
|
|
for (int i = 1; i < nLen; i++)
|
|
{
|
|
int nIndex = nPos-i;
|
|
if (nIndex < 0)
|
|
{
|
|
nIndex += nLen;
|
|
}
|
|
|
|
XRegionSide *pNextWall = (XRegionSide *)(sortSides[nIndex]->m_pSide);
|
|
if (!pNextWall)
|
|
{
|
|
continue;
|
|
}
|
|
else if (pNextWall == aRegion.Head())
|
|
{
|
|
if (pNextPt == aRegion.Head()->GetStartNode())
|
|
{
|
|
return RTNORM;
|
|
}
|
|
else
|
|
{
|
|
ASSERT(g_pMarkSide == NULL);
|
|
g_pMarkSide = pNextWall; //回退到标记
|
|
pNextWall->SetBadSide(1);
|
|
return RTNONE;
|
|
}
|
|
}
|
|
else if (aRegion.Exist(pNextWall)) //退回到pNextWall
|
|
{
|
|
ASSERT(g_pMarkSide == NULL);
|
|
g_pMarkSide = pNextWall; //回退到标记
|
|
pNextWall->SetBadSide(1);
|
|
return RTNONE; // Z Modify here on 2001/12/28
|
|
}
|
|
|
|
aRegion.Push(pNextWall);
|
|
nRetFlg = pNextWall->Trival(pNextPt, nSide);
|
|
if (nRetFlg == RTNORM)
|
|
{
|
|
return RTNORM;
|
|
}
|
|
|
|
aRegion.Pop();
|
|
if (nRetFlg == RTNONE)
|
|
{
|
|
//回退到标记
|
|
if (aRegion.Tail()!=g_pMarkSide)
|
|
{
|
|
return RTNONE;
|
|
}
|
|
|
|
g_pMarkSide = NULL; //已经到标记
|
|
return RTERROR;
|
|
}
|
|
else if (nRetFlg == RTCAN)
|
|
{
|
|
return nRetFlg;
|
|
}
|
|
else if (nRetFlg == RTERROR)
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return RTERROR;
|
|
}
|
|
|
|
XRegion* XRegionSide::GetLeftRegion() const
|
|
{
|
|
return m_pLeftRegion;
|
|
}
|
|
|
|
void XRegionSide::SetLeftRegion(XRegion * pRegion)
|
|
{
|
|
m_pLeftRegion = pRegion;
|
|
}
|
|
|
|
XRegion* XRegionSide::GetRighttRegion() const
|
|
{
|
|
return m_pRightRegion;
|
|
}
|
|
|
|
void XRegionSide::SetRightRegion(XRegion * pRegion)
|
|
{
|
|
m_pRightRegion = pRegion;
|
|
}
|
|
|
|
TCHAR XRegionSide::GetCurSide() const
|
|
{
|
|
return m_nCurSide;
|
|
}
|
|
|
|
void XRegionSide::SetCurSide(const TCHAR nCurSide)
|
|
{
|
|
m_nCurSide = nCurSide;
|
|
}
|
|
|
|
TCHAR XRegionSide::GetBadSide() const
|
|
{
|
|
return m_bBadSide;
|
|
}
|
|
|
|
void XRegionSide::SetBadSide(const TCHAR nBadSide)
|
|
{
|
|
m_bBadSide = nBadSide;
|
|
}
|
|
|
|
XSortSideOnVertex* XRegionSide::GetStartNode()const
|
|
{
|
|
return m_pStartNode;
|
|
}
|
|
|
|
void XRegionSide::SetStartNode(XSortSideOnVertex* pNode)
|
|
{
|
|
m_pStartNode = pNode;
|
|
}
|
|
|
|
XSortSideOnVertex* XRegionSide::GetEndNode()const
|
|
{
|
|
return m_pEndNode;
|
|
}
|
|
|
|
void XRegionSide::SetEndNode(XSortSideOnVertex* pNode)
|
|
{
|
|
m_pEndNode = pNode;
|
|
}
|