inline bool CAccessDistancePathVerifier::_IsBlock(unsigned int uiGridInfo) { return (uiGridInfo & (1<<20)) && (uiGridInfo & (1<<21)); } //------------------------------------------------------------------------------ inline int CAccessDistancePathVerifier::_GridPos2ID(int iX, int iY) { if (iX<0 || iX>=m_iSizeX || iY<0 ||iY>=m_iSizeY) return -1; return (iY*m_iSizeX + iX); } //------------------------------------------------------------------------------ inline void CAccessDistancePathVerifier::_Swap(int& i, int& k) { int tmp = i; i = k; k = tmp; } //------------------------------------------------------------------------------ inline float CAccessDistancePathVerifier::_DDAGetAccessDistance( int iStartX, int iStartY, int k, unsigned int** ppuiMapInfo) { float fdx = m_arrDx[k]; float fdy = m_arrDy[k]; float fCurrX = iStartX; float fCurrY = iStartY; while (fCurrX<=m_iSizeX && fCurrY<=m_iSizeY) { if (_IsBlock(ppuiMapInfo[((int)fCurrY)][(int)fCurrX])) { // 找到这个方向第一个不可通行点 break; } // 步进 fCurrX += fdx; fCurrY += fdy; } return sqrt((fCurrX-iStartX)*(fCurrX-iStartX) + (fCurrY-iStartY)*(fCurrY-iStartY)); } //------------------------------------------------------------------------------ inline float CAccessDistancePathVerifier::_GetMaxAccessAround( int iX, int iY, float** ppRealAccDist, int iDir) { float fMaxDist = _GetAccessDistance(iX, iY, ppRealAccDist, iDir); float fNeighborAcc = _GetAccessDistance(iX-1, iY, ppRealAccDist, iDir); //if (fNeighborAcc > 0.0f) //{ // fNeighborAcc = __max(fNeighborAcc, _GetAccessDistance(iX-2, iY, ppRealAccDist, iDir)); //} fMaxDist = __max(fMaxDist, fNeighborAcc); fNeighborAcc = _GetAccessDistance(iX+1, iY, ppRealAccDist, iDir); //if (fNeighborAcc > 0.0f) //{ // fNeighborAcc = __max(fNeighborAcc, _GetAccessDistance(iX+2, iY, ppRealAccDist, iDir)); //} fMaxDist = __max(fMaxDist, fNeighborAcc); fNeighborAcc = _GetAccessDistance(iX, iY-1, ppRealAccDist, iDir); //if (fNeighborAcc > 0.0f) //{ // fNeighborAcc = __max(fNeighborAcc, _GetAccessDistance(iX, iY-2, ppRealAccDist, iDir)); //} fMaxDist = __max(fMaxDist, fNeighborAcc); fNeighborAcc = _GetAccessDistance(iX, iY+1, ppRealAccDist, iDir); //if (fNeighborAcc > 0.0f) //{ // fNeighborAcc = __max(fNeighborAcc, _GetAccessDistance(iX, iY+2, ppRealAccDist, iDir)); //} fMaxDist = __max(fMaxDist, fNeighborAcc); return fMaxDist; } //------------------------------------------------------------------------------ inline float CAccessDistancePathVerifier::_GetAccessDistance( int iX, int iY, float** ppRealAccDist, int iDir) { assert(iDir <= NUM_AROUND_DIRECTIONS); if (iX<0 || iX>=m_iSizeX || iY<0 || iY>m_iSizeY) return 0.0f; int iGridID = iY*m_iSizeX + iX; return (ppRealAccDist[iGridID]==0) ? 0.0f : (ppRealAccDist[iGridID][iDir]); } //------------------------------------------------------------------------------ inline bool CAccessDistancePathVerifier::VerifiyWalkable( int iStartX, int iStartY, int iEndX, int iEndY) { // y 小的为 start, 大的为 end if (iStartY > iEndY) { _Swap(iStartX, iEndX); _Swap(iStartY, iEndY); } int iDX = iEndX - iStartX; int iDY = iEndY - iStartY; // 根据斜率计算角度 float fSlop = (float)(iDY) / (float)(iDX); float fAngle = atan(fSlop); // 弧度 if (iDX < 0) {fAngle += M_PI;} // 判断 fAngle 落在哪个区间 int k = (fAngle + m_fHalfDAngle) / m_fDAngle; // 从表中查询在 k 方向所能到达的距离 int iHalfGridID = ((iStartY>>1)*m_iHalfSizeX) + (iStartX>>1); if (m_ucAccessDistance[iHalfGridID] == 0) { // 该点不可行走 return false; } int iAccDist = m_ucAccessDistance[iHalfGridID][k]; // 用距离平方比较 return ((iAccDist*iAccDist)<<2) >= (iDX*iDX + iDY*iDY); }