///////////////////////////////////////////////// // // 使用RecastNavigation库进行寻路的测试程序 // Written by: Liu Gang. July.11.2020. // ///////////////////////////////////////////////// #include #include #include #include #include #include "tools.h" #include "../RecastNavDll/RecastDll.h" std::string _strLastError; int DoRecast(std::string mapPathName, std::string posFrom, std::string posTo); int main(int argc, char* argv[]) { std::cout << "共有" << argc << "个参数" << std::endl; for (int i = 0; i < argc; i++) { std::cout << argv[i] << std::endl; } if (argc == 2 && _stricmp(argv[1], "/?") == 0) { printf_s("Recast工具 参数说明: "); printf_s(" Recast [寻路文件名, 含路径] [(起点坐标:) x,y] [(终点坐标:) x,y]"); printf_s(" 举例:"); printf_s(" Recast solo_navmesh.bin 33.07,13.46 1103.89,478.21"); return 0; } if (argc == 5) //第一个参数是可执行文件自身,第二个参数是Recast标志,第三个参数是文件名,第四个参数是起点,第五个参数是终点 { int ret = DoRecast(argv[2], argv[3], argv[4]); if (ret == 0) { return 0; } else { std::string strRet = std::to_string(ret); std::string error = "Recast工具 错误(" + strRet + ") - " + _strLastError; printf_s(error.c_str()); return ret; } } printf_s("Recast工具 参数错误(-1)!请使用 /? 查看参数说明。"); return -1; } int Find2(int id, std::string mapPathName, const std::string posFrom, const std::string posTo); int DoRecast(const std::string mapPathName, const std::string posFrom, const std::string posTo) { // 1,初始化 if (!recast_init()) { _strLastError = "Recast 初始化失败!"; return -11; } // 2,加载地图101 int id1 = 101; if (!recast_loadmap(id1, mapPathName.c_str())) { _strLastError = "地图创建失败!- " + mapPathName; return -12; } // 2,加载地图102 int id2 = 102; if (!recast_loadmap(id2, mapPathName.c_str())) { _strLastError = "地图创建失败!- " + mapPathName; return -12; } // 3,地图101开始寻路 printf_s("寻路开始...\n"); int ret = Find2(id1, mapPathName, posFrom, posTo); if (ret < 0) { printf_s(_strLastError.c_str()); } printf_s("...寻路结束 - ret:%d\n\n", ret); // 3,地图102开始寻路 printf_s("寻路开始...\n"); ret = Find2(id2, mapPathName, posFrom, posTo); if (ret < 0) { printf_s(_strLastError.c_str()); } printf_s("...寻路结束 - ret:%d\n\n", ret); // 4,释放地图 recast_freemap(id1); recast_freemap(id2); // 5,释放Recast引擎 recast_fini(); printf_s("Recast 寻路成功!"); return 0; } int Find2(int id, std::string mapPathName, const std::string posFrom, const std::string posTo) { Tools::dtStatus status; std::vector strsFrom = Tools::split(posFrom, ","); std::vector strsTo = Tools::split(posTo, ","); //注意在Unity中因为坐标系原因,x需要为相反数 float spos[3] = {stof(strsFrom[0]), stof(strsFrom[1]), stof(strsFrom[2])}; float epos[3] = {stof(strsTo[0]), stof(strsTo[1]), stof(strsTo[2])}; // 1,寻路 status = recast_findpath(id, spos, epos); if (Tools::dtStatusFailed(status)) { int statusDetail = status & Tools::DT_STATUS_DETAIL_MASK; std::string strDetail = std::to_string(statusDetail); _strLastError = "寻路失败!错误码<" + strDetail + ">"; if (statusDetail == Tools::DT_COORD_INVALID) { char szFrom[256], szTo[256]; sprintf_s(szFrom, sizeof(szFrom), "%f, %f, %f", spos[0], spos[1], spos[2]); sprintf_s(szTo, sizeof(szTo), "%f, %f, %f", epos[0], epos[1], epos[2]); std::string strFrom = szFrom, strTo = szTo; _strLastError += " - 坐标非法!From<" + strFrom + "> To<" + strTo + ">"; } return -13; } else if (Tools::dtStatusInProgress(status)) { return -14; } float* fixPos = new float[3]; memcpy(fixPos, recast_getfixposition(id, spos), sizeof(float) * 3); float* fixPos2 = new float[3]; memcpy(fixPos2, recast_getfixposition(id, epos), sizeof(float) * 3); // 2,得到实际(平滑)路径 recast_smooth(id, 2, 0.5); // 寻路成功! // 3,得到凸多边形id序列 std::string format = " 起点<%f,%f,%f> 终点<%f,%f,%f>\n"; printf_s(format.c_str(), spos[0], spos[1], spos[2], epos[0], epos[1], epos[2]); int m_npolys = recast_getcountpoly(id); unsigned int* m_polys = recast_getpathpoly(id); std::string outputPoly = " 路线地块序号 (" + std::to_string(m_npolys) + "): \n "; for (int i = 0; i < m_npolys; ++i) { std::string strPoly = std::to_string((m_polys[i])); outputPoly += strPoly + ", "; } outputPoly += "\n"; printf_s(outputPoly.c_str()); // 4,得到寻路路径的坐标序列 int m_nsmoothPath = recast_getcountsmooth(id); float* m_smoothPath = recast_getpathsmooth(id); std::string outputSmooth = " 路线 (" + std::to_string(m_nsmoothPath) + "): \n"; for (int i = 0; i < m_nsmoothPath; ++i) { std::string strSmooth = std::to_string(m_smoothPath[i * 3]) + "," + std::to_string(m_smoothPath[i * 3 + 1]) + "," + std::to_string(m_smoothPath[i * 3 + 2]); outputSmooth += " <" + strSmooth + "> \n"; } printf_s(outputSmooth.c_str()); return 1; }