//------------------------------------------------------------------------------ inline bool CPieceTemplatePathVerifier::VerifiyWalkable(int iStartX, int iStartY, int iEndX, int iEndY, bool bUseExtraDDATest) { // 检查两点是否都在地图范围内 assert(iStartX>=0 && iStartX<=m_iSizeX && iStartY>=0 && iStartY<=m_iSizeY && iEndX>=0 && iEndX<=m_iSizeX && iEndY>=0 && iEndY<=m_iSizeY); // 起点, 终点所在 piece 的坐标 int iStartPieceX = iStartX >> 3; // / MAP_PIECE_DIM; int iStartPieceY = iStartY >> 3; // / MAP_PIECE_DIM; int iEndPieceX = iEndX >>3; // / MAP_PIECE_DIM; int iEndPieceY = iEndY >>3; /// MAP_PIECE_DIM; int iDX = iEndX - iStartX; // x 方向差值 int iDY = iEndY - iStartY; // y 方向差值 bool bMajorX = abs(iDX) >= abs(iDY); // 是 x 方向主分割还是 y 方向主分割 // 步数为 major 方向 piece 差值 int iSteps = bMajorX ? abs(iEndPieceX-iStartPieceX) : abs(iEndPieceY-iStartPieceY); // 步进量 float fdx = 0.0f; float fdy = 0.0f; float fSlop = (float)iDY / (float)iDX; if (bMajorX) { fdx = (iDX>0) ? MAP_PIECE_DIM : -MAP_PIECE_DIM; fdy = fdx *fSlop; } else { fdy = (iDY>0) ? MAP_PIECE_DIM : -MAP_PIECE_DIM; fdx = fdy / fSlop; } float fCurrX = iStartX; // 当前点 float fCurrY = iStartY; float fLastX = fCurrX; // 前步点 float fLastY = fCurrY; for (int i=1; i<=iSteps; i++, fCurrX+=fdx, fCurrY+=fdy) { if (i == iSteps) { // 最后一个步骤, 测试到终点 fCurrX = iEndX; fCurrY = iEndY; } else if (i == 0) { // do nothing continue; } // piece 坐标 int iLastPieceX = ((int)fLastX) / MAP_PIECE_DIM; int iLastPieceY = ((int)fLastY) / MAP_PIECE_DIM; int iLastPieceID = iLastPieceY * m_iNumPiecesX + iLastPieceX; // 前一个 piece id int iCurrPieceX = ((int)fCurrX) / MAP_PIECE_DIM; int iCurrPieceY = ((int)fCurrY) / MAP_PIECE_DIM; int iCurrPieceID = iCurrPieceY * m_iNumPiecesX + iCurrPieceX; // 当前 piece id // last 点 和 current 点 在其 piece 内的 id int iLastLocalID = _MapPosToPieceLocalID(fLastX, fLastY); int iCurrLocalID = _MapPosToPieceLocalID(fCurrX, fCurrY); if (!_CanAccess(iLastPieceX, iLastPieceY, iLastPieceID, iLastLocalID, iCurrPieceX, iCurrPieceY, iCurrPieceID, iCurrLocalID)) { return false; } // 将 curr 复制给 last fLastX = fCurrX; fLastY = fCurrY; } return true; } //------------------------------------------------------------------------------ inline int CPieceTemplatePathVerifier::_MapPosToPieceID(int iX, int iY) { //return (iY/MAP_PIECE_DIM)*m_iNumPiecesX + iX/MAP_PIECE_DIM; return (iY>>3)*m_iNumPiecesX + (iX>>3); } //------------------------------------------------------------------------------ inline int CPieceTemplatePathVerifier::_MapPosToPieceLocalID(int iX, int iY) { //return (iY%MAP_PIECE_DIM)*MAP_PIECE_DIM + iX%MAP_PIECE_DIM; return ((iY%MAP_PIECE_DIM)<<3) + iX%MAP_PIECE_DIM; } //------------------------------------------------------------------------------ inline bool CPieceTemplatePathVerifier::_CanAccess(int iLastPieceX, int iLastPieceY, int iLastPieceID, int iLastLocalID, int iCurrPieceX, int iCurrPieceY, int iCurrPieceID, int iCurrLocalID) { // 判断 last piece 和 curr piece 的位置关系 if (iLastPieceX < iCurrPieceX) { if (iLastPieceY < iCurrPieceY) { ///////////////// // 左下 - 右上 ///////////////// // 根据位置关系 和 startID, endID 找到模板 uint64* arrTemp = &(m_pAccTempGen->m_arrAccTmpUpRight[iLastLocalID][iCurrLocalID][0]); return _IsFitTemplat(iLastPieceID, iCurrPieceID, CMapAccessTemplateGenerator::AD_UPRIGHT, arrTemp); } else if (iLastPieceY == iCurrPieceY) { // 左 - 右 uint64* arrTemp = &(m_pAccTempGen->m_arrAccTmpRight[iLastLocalID][iCurrLocalID][0]); return _IsFitTemplat(iLastPieceID, iCurrPieceID, CMapAccessTemplateGenerator::AD_RIGHT, arrTemp); } else if (iLastPieceY > iCurrPieceY) { // 左上 - 右下 uint64* arrTemp = &(m_pAccTempGen->m_arrAccTmpUpLeft[iCurrLocalID][iLastLocalID][0]); return _IsFitTemplat(iCurrPieceID, iLastPieceID, CMapAccessTemplateGenerator::AD_UPLEFT, arrTemp); } } else if (iLastPieceX == iCurrPieceX) { if (iLastPieceY < iCurrPieceY) { // 下 - 上 uint64* arrTemp = &(m_pAccTempGen->m_arrAccTmpUp[iLastLocalID][iCurrLocalID][0]); return _IsFitTemplat(iLastPieceID, iCurrPieceID, CMapAccessTemplateGenerator::AD_UP, arrTemp); } else if (iLastPieceY == iCurrPieceY) { // self uint64* arrTemp = &(m_pAccTempGen->m_arrAccTmpSelf[iLastLocalID][iCurrLocalID]); return _IsFitTemplat(iLastPieceID, iCurrPieceID, CMapAccessTemplateGenerator::AD_SELF, arrTemp); } else if (iLastPieceY > iCurrPieceY) { // 上 - 下 uint64* arrTemp = &(m_pAccTempGen->m_arrAccTmpUp[iCurrLocalID][iLastLocalID][0]); return _IsFitTemplat(iCurrPieceID, iLastPieceID, CMapAccessTemplateGenerator::AD_UP, arrTemp); } } else // iLastPieceX > iCurrPieceX { if (iLastPieceY < iCurrPieceY) { // 右下 - 左上 uint64* arrTemp = &(m_pAccTempGen->m_arrAccTmpUpLeft[iLastLocalID][iCurrLocalID][0]); return _IsFitTemplat(iLastPieceID, iCurrPieceID, CMapAccessTemplateGenerator::AD_UPLEFT, arrTemp); } else if (iLastPieceY == iCurrPieceY) { // 右 - 左 uint64* arrTemp = &(m_pAccTempGen->m_arrAccTmpRight[iCurrLocalID][iLastLocalID][0]); return _IsFitTemplat(iCurrPieceID, iLastPieceID, CMapAccessTemplateGenerator::AD_RIGHT, arrTemp); } else if (iLastPieceY > iCurrPieceY) { // 右上 - 左下 uint64* arrTemp = &(m_pAccTempGen->m_arrAccTmpUpRight[iCurrLocalID][iLastLocalID][0]); return _IsFitTemplat(iCurrPieceID, iLastPieceID, CMapAccessTemplateGenerator::AD_UPRIGHT, arrTemp); } } return true; } //------------------------------------------------------------------------------ inline bool CPieceTemplatePathVerifier::_IsFitTemplat(int iStartPiece, int iEndPiece, CMapAccessTemplateGenerator::eAccessDirection eDir, const uint64* arrTemp) { if (eDir == CMapAccessTemplateGenerator::AD_SELF) { return ((m_pMap[iStartPiece] & (*arrTemp)) == (*arrTemp)); } else if (eDir == CMapAccessTemplateGenerator::AD_RIGHT || eDir == CMapAccessTemplateGenerator::AD_UP) { return ((m_pMap[iStartPiece] & arrTemp[0]) == arrTemp[0]) && ((m_pMap[iEndPiece] & arrTemp[1]) == arrTemp[1]); } else if (eDir == CMapAccessTemplateGenerator::AD_UPLEFT) { return ((m_pMap[iStartPiece] & arrTemp[0]) == arrTemp[0] && (m_pMap[iStartPiece-1] & arrTemp[1]) == arrTemp[1] && (m_pMap[iEndPiece] & arrTemp[2]) == arrTemp[2] && (m_pMap[iEndPiece+1] & arrTemp[3]) == arrTemp[3]); } else if (eDir == CMapAccessTemplateGenerator::AD_UPRIGHT) { return ((m_pMap[iStartPiece] & arrTemp[0]) == arrTemp[0] && (m_pMap[iEndPiece-1] & arrTemp[1]) == arrTemp[1] && (m_pMap[iEndPiece] & arrTemp[2]) == arrTemp[2] && (m_pMap[iStartPiece+1] & arrTemp[3]) == arrTemp[3]); } return false; } //------------------------------------------------------------------------------