i have pathfind for my game, can u change my pathfind so it can avoid crowd agent? for example after building path, u create agent and move it to endpos avoid other agent and then return that path? std::vector<glm::vec3> NavMeshBuilder::FindPath(const glm::vec3& start, const glm::vec3& end, const dtCrowd* crowd) { constexpr int MAX_POLYS = 512 * 8 * 8 * 8; constexpr int MAX_SMOOTH = 2048 * 8 * 8; float polyPickExt[3] = { 0.5f, 2.0f, 0.5f }; dtQueryFilter filter; filter.setIncludeFlags(SAMPLE_POLYFLAGS_WALK ^ SAMPLE_POLYFLAGS_JUMP); filter.setExcludeFlags(SAMPLE_POLYFLAGS_SWIM); filter.setAreaCost(SAMPLE_POLYAREA_WATER, 65534); // Set a high cost for water areas dtPolyRef startRef, endRef; float startPos[3] = { start.x, start.y, start.z }; float endPos[3] = { end.x, end.y, end.z }; float nearestStart[3], nearestEnd[3]; m_navQuery->findNearestPoly(startPos, polyPickExt, &filter, &startRef, nearestStart); m_navQuery->findNearestPoly(endPos, polyPickExt, &filter, &endRef, nearestEnd); if (!startRef || !endRef) { return {}; } std::vector<dtPolyRef> polys(MAX_POLYS); int npolys = 0; m_navQuery->findPath(startRef, endRef, nearestStart, nearestEnd, &filter, polys.data(), &npolys, MAX_POLYS); if (npolys == 0) { return {}; } std::vector<float> smoothPath(MAX_SMOOTH * 3); int nsmoothPath = 0; if (npolys) { float iterPos[3], targetPos[3]; m_navQuery->closestPointOnPoly(startRef, nearestStart, iterPos, 0); m_navQuery->closestPointOnPoly(polys[npolys - 1], nearestEnd, targetPos, 0); static const float STEP_SIZE = 1.0f; static const float SLOP = 0.01f; dtVcopy(&smoothPath[nsmoothPath * 3], iterPos); nsmoothPath++; while (npolys && nsmoothPath < MAX_SMOOTH) { float steerPos[3]; unsigned char steerPosFlag; dtPolyRef steerPosRef; if (!getSteerTarget(m_navQuery, iterPos, targetPos, SLOP, polys.data(), npolys, steerPos, steerPosFlag, steerPosRef)) break; bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END) ? true : false; bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ? true : false; float delta[3], len; dtVsub(delta, steerPos, iterPos); len = dtMathSqrtf(dtVdot(delta, delta)); if ((endOfPath || offMeshConnection) && len < STEP_SIZE) len = 1; else len = STEP_SIZE / len; float moveTgt[3]; dtVmad(moveTgt, iterPos, delta, len); float result[3]; dtPolyRef visited[16]; int nvisited = 0; m_navQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &filter, result, visited, &nvisited, 16); npolys = dtMergeCorridorStartMoved(polys.data(), npolys, MAX_POLYS, visited, nvisited); npolys = fixupShortcuts(polys.data(), npolys, m_navQuery); float h = 0; m_navQuery->getPolyHeight(polys[0], result, &h); result[1] = h; dtVcopy(iterPos, result); if (endOfPath && inRange(iterPos, steerPos, 0.5f, 1.0f)) { dtVcopy(iterPos, targetPos); if (nsmoothPath < MAX_SMOOTH) { dtVcopy(&smoothPath[nsmoothPath * 3], iterPos); nsmoothPath++; } break; } else if (offMeshConnection && inRange(iterPos, steerPos, 0.5f, 1.0f)) { float startPos[3], endPos[3]; dtPolyRef prevRef = 0, polyRef = polys[0]; int npos = 0; while (npos < npolys && polyRef != steerPosRef) { prevRef = polyRef; polyRef = polys[npos]; npos++; } for (int i = npos; i < npolys; ++i) polys[i - npos] = polys[i]; npolys -= npos; dtStatus status = m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos); if (dtStatusSucceed(status)) { if (nsmoothPath < MAX_SMOOTH) { dtVcopy(&smoothPath[nsmoothPath * 3], startPos); nsmoothPath++; if (nsmoothPath & 1) { dtVcopy(&smoothPath[nsmoothPath * 3], startPos); nsmoothPath++; } } dtVcopy(iterPos, endPos); float eh = 0.0f; m_navQuery->getPolyHeight(polys[0], iterPos, &eh); iterPos[1] = eh; } } if (nsmoothPath < MAX_SMOOTH) { dtVcopy(&smoothPath[nsmoothPath * 3], iterPos); nsmoothPath++; } } } std::vector<glm::vec3> result; result.reserve(nsmoothPath); for (int i = 0; i < nsmoothPath; ++i) { result.emplace_back( smoothPath[i * 3], smoothPath[i * 3 + 1], smoothPath[i * 3 + 2] ); } return result; }