public static CellPos GetFirstWalkableCell(ICellMapView view, Vector3 from, Vector3 to) { CellPos start = new CellPos(-1, -1), end = new CellPos(-1, -1), ret = new CellPos(-1, -1); view.GetCell(from, out start.row, out start.col); if (view.CanPass(start.row, start.col)) { ret = start; } else { view.GetCell(to, out end.row, out end.col); from = view.GetCellCenter(start.row, start.col); to = view.GetCellCenter(end.row, end.col); from.Y = 0; to.Y = 0; float step = view.RadiusLength * 2; float angle = Geometry.GetYAngle(new Vector2(from.X, from.Z), new Vector2(to.X, to.Z)); float xstep = step * (float)Math.Sin(angle); float zstep = step * (float)Math.Cos(angle); int count = (int)((to - from).Length() / step); for (int ix = 0; ix < count; ++ix) { from.X += xstep; from.Z += zstep; int row, col; view.GetCell(from, out row, out col); if (view.CanPass(row, col)) { ret.row = row; ret.col = col; break; } } } return(ret); }
public static bool IsWalkable(ICellMapView view, Vector3 srcPos, Vector3 dir) { int row = 0; int col = 0; view.GetCell(srcPos, out row, out col); float r = view.RadiusLength * 2; Vector3 targetPos = view.GetCellCenter(row, col); dir.Normalize(); targetPos.X += r * dir.X; targetPos.Z += r * dir.Z; int oRow = 0; int oCol = 0; view.GetCell(targetPos, out oRow, out oCol); bool ret = true; if (oRow != row || oCol != col) { ret = view.CanPass(oRow, oCol); } return(ret); }
public static bool GetWalkablePosition(ICellMapView view, Vector3 targetPos, Vector3 srcPos, ref Vector3 pos) { bool ret = false; const int c_MaxCheckCells = 3; int row = 0; int col = 0; view.GetCell(targetPos, out row, out col); float radian = Geometry.GetYAngle(new Vector2(targetPos.X, targetPos.Z), new Vector2(srcPos.X, srcPos.Z)); if (radian >= Math.PI / 4 && radian < Math.PI * 3 / 4)//右边 { for (int ci = 1; ci <= c_MaxCheckCells; ++ci) { for (int ri = 0; ri <= c_MaxCheckCells; ++ri) { int row_ = row + ri; int col_ = col + ci; if (view.IsCellValid(row_, col_)) { if (view.CanPass(row_, col_)) { pos = view.GetCellCenter(row_, col_); ret = true; goto exit; } } if (ri > 0) { row_ = row - ri; if (view.IsCellValid(row_, col_)) { if (view.CanPass(row_, col_)) { pos = view.GetCellCenter(row_, col_); ret = true; goto exit; } } } } } } else if (radian >= Math.PI * 3 / 4 && radian < Math.PI * 5 / 4)//上边 { for (int ri = 1; ri <= c_MaxCheckCells; ++ri) { for (int ci = 0; ci <= c_MaxCheckCells; ++ci) { int row_ = row - ri; int col_ = col + ci; if (view.IsCellValid(row_, col_)) { if (view.CanPass(row_, col_)) { pos = view.GetCellCenter(row_, col_); ret = true; goto exit; } } if (ci > 0) { col_ = col - ci; if (view.IsCellValid(row_, col_)) { if (view.CanPass(row_, col_)) { pos = view.GetCellCenter(row_, col_); ret = true; goto exit; } } } } } } else if (radian >= Math.PI * 5 / 4 && radian < Math.PI * 7 / 4)//左边 { for (int ci = 1; ci <= c_MaxCheckCells; ++ci) { for (int ri = 0; ri <= c_MaxCheckCells; ++ri) { int row_ = row + ri; int col_ = col - ci; if (view.IsCellValid(row_, col_)) { if (view.CanPass(row_, col_)) { pos = view.GetCellCenter(row_, col_); ret = true; goto exit; } } if (ri > 0) { row_ = row - ri; if (view.IsCellValid(row_, col_)) { if (view.CanPass(row_, col_)) { pos = view.GetCellCenter(row_, col_); ret = true; goto exit; } } } } } } else//下边 { for (int ri = 1; ri <= c_MaxCheckCells; ++ri) { for (int ci = 0; ci <= c_MaxCheckCells; ++ci) { int row_ = row + ri; int col_ = col + ci; if (view.IsCellValid(row_, col_)) { if (view.CanPass(row_, col_)) { pos = view.GetCellCenter(row_, col_); ret = true; goto exit; } } if (ci > 0) { col_ = col - ci; if (view.IsCellValid(row_, col_)) { if (view.CanPass(row_, col_)) { pos = view.GetCellCenter(row_, col_); ret = true; goto exit; } } } } } } exit: return(ret); }