/// @par /// /// May be called more than once to purge and re-initialize the crowd. bool dtCrowd::init(const int maxAgents, const float maxAgentRadius, dtNavMesh* nav) { purge(); m_maxAgents = maxAgents; m_maxAgentRadius = maxAgentRadius; dtVset(m_ext, m_maxAgentRadius*2.0f,m_maxAgentRadius*1.5f,m_maxAgentRadius*2.0f); m_grid = dtAllocProximityGrid(); if (!m_grid) return false; if (!m_grid->init(m_maxAgents*4, maxAgentRadius*3)) return false; m_obstacleQuery = dtAllocObstacleAvoidanceQuery(); if (!m_obstacleQuery) return false; if (!m_obstacleQuery->init(6, 8)) return false; // Init obstacle query params. memset(m_obstacleQueryParams, 0, sizeof(m_obstacleQueryParams)); for (int i = 0; i < DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS; ++i) { dtObstacleAvoidanceParams* params = &m_obstacleQueryParams[i]; params->velBias = 0.4f; params->weightDesVel = 2.0f; params->weightCurVel = 0.75f; params->weightSide = 0.75f; params->weightToi = 2.5f; params->horizTime = 2.5f; params->gridSize = 33; params->adaptiveDivs = 7; params->adaptiveRings = 2; params->adaptiveDepth = 5; } // Allocate temp buffer for merging paths. m_maxPathResult = 256; m_pathResult = (dtPolyRef*)dtAlloc(sizeof(dtPolyRef)*m_maxPathResult, DT_ALLOC_PERM); if (!m_pathResult) return false; if (!m_pathq.init(m_maxPathResult, MAX_PATHQUEUE_NODES, nav)) return false; m_agents = (dtCrowdAgent*)dtAlloc(sizeof(dtCrowdAgent)*m_maxAgents, DT_ALLOC_PERM); if (!m_agents) return false; m_activeAgents = (dtCrowdAgent**)dtAlloc(sizeof(dtCrowdAgent*)*m_maxAgents, DT_ALLOC_PERM); if (!m_activeAgents) return false; m_agentAnims = (dtCrowdAgentAnimation*)dtAlloc(sizeof(dtCrowdAgentAnimation)*m_maxAgents, DT_ALLOC_PERM); if (!m_agentAnims) return false; for (int i = 0; i < m_maxAgents; ++i) { new(&m_agents[i]) dtCrowdAgent(); m_agents[i].active = 0; if (!m_agents[i].corridor.init(m_maxPathResult)) return false; } for (int i = 0; i < m_maxAgents; ++i) { m_agentAnims[i].active = 0; } // The navquery is mostly used for local searches, no need for large node pool. m_navquery = dtAllocNavMeshQuery(); if (!m_navquery) return false; if (dtStatusFailed(m_navquery->init(nav, MAX_COMMON_NODES))) return false; return true; }
/// @par /// /// May be called more than once to purge and re-initialize the crowd. bool dtCrowd::init(const int maxAgents, const float maxAgentRadius, dtNavMesh* nav) { purge(); m_maxAgents = maxAgents; m_maxAgentRadius = maxAgentRadius; m_numActiveAgents = 0; dtVset(m_ext, m_maxAgentRadius*2.0f,m_maxAgentRadius*1.5f,m_maxAgentRadius*2.0f); m_grid = dtAllocProximityGrid(); if (!m_grid) return false; if (!m_grid->init(m_maxAgents*4, maxAgentRadius*3)) return false; // [UE4] moved avoidance query init to separate function // Allocate temp buffer for merging paths. m_maxPathResult = 256; m_pathResult = (dtPolyRef*)dtAlloc(sizeof(dtPolyRef)*m_maxPathResult, DT_ALLOC_PERM); if (!m_pathResult) return false; if (!m_pathq.init(m_maxPathResult, MAX_PATHQUEUE_NODES, nav)) return false; m_agents = (dtCrowdAgent*)dtAlloc(sizeof(dtCrowdAgent)*m_maxAgents, DT_ALLOC_PERM); if (!m_agents) return false; m_activeAgents = (dtCrowdAgent**)dtAlloc(sizeof(dtCrowdAgent*)*m_maxAgents, DT_ALLOC_PERM); if (!m_activeAgents) return false; m_agentAnims = (dtCrowdAgentAnimation*)dtAlloc(sizeof(dtCrowdAgentAnimation)*m_maxAgents, DT_ALLOC_PERM); if (!m_agentAnims) return false; for (int i = 0; i < m_maxAgents; ++i) { new(&m_agents[i]) dtCrowdAgent(); m_agents[i].active = 0; if (!m_agents[i].corridor.init(m_maxPathResult)) return false; } for (int i = 0; i < m_maxAgents; ++i) { m_agentAnims[i].active = 0; } for (int i = 0; i < DT_MAX_AREAS; i++) { m_raycastFilter.setAreaCost(i, DT_UNWALKABLE_POLY_COST); } // The navquery is mostly used for local searches, no need for large node pool. m_navquery = dtAllocNavMeshQuery(); if (!m_navquery) return false; if (dtStatusFailed(m_navquery->init(nav, MAX_COMMON_NODES))) return false; return true; }