//------------------------------------------------------------------------------ inline void CMapAccessTemplateGenerator::_InitDDAParams(const int iDX, const int iDY, float& dx, float& dy, int& iSteps) { iSteps = __max(abs(iDX), abs(iDY)); if (iSteps != 0) { dx = ((float)iDX)/iSteps; dy = ((float)iDY)/iSteps; } else { dx = 0.0f; dy = 0.0f; } } //------------------------------------------------------------------------------ inline bool CMapAccessTemplateGenerator::_DDASetTemplate(int iStartX, int iStartY, int iEndX, int iEndY, eAccessDirection eDir, uint64& uiTemp0) { assert(eDir == AD_SELF); // 只用做 self piece 的 模板生成 int iSteps; // 步进次数 float dx, dy; // 步进值 _InitDDAParams(iEndX-iStartX, iEndY-iStartY, dx, dy, iSteps); // 进行 iSteps 次的步进,将每步经过的点记入模板 float fCurrX = (float)iStartX; float fCurrY = (float)iStartY; for (int i=0; i<=iSteps; i++, fCurrX += dx, fCurrY += dy) { int iGridID = ((int)fCurrY) * MAP_PIECE_DIM + (int)fCurrX; _SetBit(uiTemp0, iGridID); } return true; } //------------------------------------------------------------------------------ inline bool CMapAccessTemplateGenerator::_DDASetTemplate(int iStartX, int iStartY, int iEndX, int iEndY, eAccessDirection eDir,uint64& uiTemp0, uint64& uiTemp1) { // uiTemp0 是 start piece 模板, uiTemp1 是 end piece 模板. // 处理到上方或者右方 piece 的情况 assert(eDir == AD_UP || eDir == AD_RIGHT); // 从本 piece 某点到相邻 piece 同坐标点的偏移值 int iOffsetX = 0; int iOffsetY = 0; if (eDir == AD_UP) {iOffsetY = MAP_PIECE_DIM;} else if (eDir == AD_RIGHT) {iOffsetX = MAP_PIECE_DIM;} int iSteps; // 步进次数 float dx, dy; // 步进值 _InitDDAParams(iEndX+iOffsetX-iStartX, iEndY+iOffsetY-iStartY, dx, dy, iSteps); // 进行 iSteps 次的步进,将每步经过的点记入模板 float fCurrX = (float)iStartX; float fCurrY = (float)iStartY; for (int i=0; i<=iSteps; i++, fCurrX += dx, fCurrY += dy) { // 判断 curr 点是在本 piece 还是在相邻 piece if (fCurrY >= MAP_PIECE_DIM) { // AD_UP int iGridID = ((int)(fCurrY-MAP_PIECE_DIM)) * MAP_PIECE_DIM + (int)fCurrX; _SetBit(uiTemp1, iGridID); } else if (fCurrX >= MAP_PIECE_DIM) { // AD_RIGHT int iGridID = ((int)(fCurrY)) * MAP_PIECE_DIM + (int)(fCurrX-MAP_PIECE_DIM); _SetBit(uiTemp1, iGridID); } else { // AD_SELF int iGridID = ((int)(fCurrY)) * MAP_PIECE_DIM + (int)(fCurrX); _SetBit(uiTemp0, iGridID); } } return true; } //------------------------------------------------------------------------------ inline bool CMapAccessTemplateGenerator::_DDASetTemplate(int iStartX, int iStartY, int iEndX, int iEndY, eAccessDirection eDir,uint64& uiTemp0, uint64& uiTemp1, uint64& uiTemp2, uint64& uiTemp3) { // 处理到左上或者右上的情况 assert(eDir == AD_UPLEFT || eDir == AD_UPRIGHT); // 从本 piece 某点到相邻 piece 同坐标点的偏移值 int iOffsetX = 0; int iOffsetY = 0; if (eDir == AD_UPLEFT) { iOffsetX = -MAP_PIECE_DIM; iOffsetY = MAP_PIECE_DIM; } else if (eDir == AD_UPRIGHT) { iOffsetX = MAP_PIECE_DIM; iOffsetY = MAP_PIECE_DIM; } int iSteps; // 步进次数 float dx, dy; // 步进值 _InitDDAParams(iEndX+iOffsetX-iStartX, iEndY+iOffsetY-iStartY, dx, dy, iSteps); // 进行 iSteps 次的步进,将每步经过的点记入模板 float fCurrX = (float)iStartX; float fCurrY = (float)iStartY; for (int i=0; i<=iSteps; i++, fCurrX += dx, fCurrY += dy) { // 按照顺时针方向 if (eDir == AD_UPLEFT) { // 情况比较复杂, 如果目标点在左上, 4 个模板对应关系为 // temp0 - self // temp1 - left // temp2 - upleft // temp3 - up if (fCurrX>=0.0f && fCurrY < MAP_PIECE_DIM) { // self int iGridID = ((int)(fCurrY)) * MAP_PIECE_DIM + (int)fCurrX; _SetBit(uiTemp0, iGridID); } else if (fCurrX<0.0f && fCurrY= MAP_PIECE_DIM) { // upleft int iGridID = ((int)(fCurrY - MAP_PIECE_DIM)) * MAP_PIECE_DIM + (int)(fCurrX + MAP_PIECE_DIM); _SetBit(uiTemp2, iGridID); } else if (fCurrX >= 0.0f && fCurrY >= MAP_PIECE_DIM) { // up int iGridID = ((int)(fCurrY - MAP_PIECE_DIM)) * MAP_PIECE_DIM + (int)(fCurrX); _SetBit(uiTemp3, iGridID); } } else if (eDir == AD_UPRIGHT) { // 如果目标点在右上, 对应关系为 // temp0 - self // temp1 - up // temp2 - upright // temp3 - right if (fCurrX < MAP_PIECE_DIM && fCurrY < MAP_PIECE_DIM) { // self int iGridID = ((int)(fCurrY)) * MAP_PIECE_DIM + (int)fCurrX; _SetBit(uiTemp0, iGridID); } else if (fCurrX < MAP_PIECE_DIM && fCurrY >= MAP_PIECE_DIM) { // up int iGridID = ((int)(fCurrY - MAP_PIECE_DIM)) * MAP_PIECE_DIM + (int)(fCurrX); _SetBit(uiTemp1, iGridID); } else if (fCurrX >= MAP_PIECE_DIM && fCurrY >= MAP_PIECE_DIM) { // upright int iGridID = ((int)(fCurrY - MAP_PIECE_DIM)) * MAP_PIECE_DIM + (int)(fCurrX - MAP_PIECE_DIM); _SetBit(uiTemp2, iGridID); } else if (fCurrX >= MAP_PIECE_DIM && fCurrY < MAP_PIECE_DIM) { // right int iGridID = ((int)(fCurrY)) * MAP_PIECE_DIM + (int)(fCurrX - MAP_PIECE_DIM); _SetBit(uiTemp3, iGridID); } } } return true; } //------------------------------------------------------------------------------ inline void CMapAccessTemplateGenerator::_SetBit(uint64& uiTag, int iWhere) { // 忽略参数合法性检查提高效率 assert(iWhere < 64 && iWhere >= 0); uint64 uiTmp = 1ll << iWhere; uiTag |= uiTmp; } //------------------------------------------------------------------------------