PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/Core/Dependencies/Engine/AI/AIWorldManager.cpp

https://bitbucket.org/barakianc/nvidia-physx-and-apex-in-gge
C++ | 746 lines | 540 code | 101 blank | 105 comment | 131 complexity | 7f4aef2bce56d58cf42337ad5a15c732 MD5 | raw file
  1. #include "StdAfx.h"
  2. #include "AIWorldManager.h"
  3. #include "InputGeom.h"
  4. #include "Ogre.h"
  5. #include "Sample.h"
  6. #include "HavokWrapper.h"
  7. #include "Ogre.h"
  8. #include "DetourCommon.h"
  9. #include "NavMeshTesterTool.h"
  10. #include "DetourDraw.h"
  11. /************************************************************************/
  12. /* GENERAL METHODS */
  13. /************************************************************************/
  14. bool AIWorldManager::useRecast = false;
  15. AIWorldManager::AIWorldManager() :
  16. mActiveCrowdId (0),
  17. mActiveAgentId(-1),
  18. mCrowdsHandler(0),
  19. mCrowdsNo(0),
  20. mSample (0),
  21. staticWorld(0),
  22. mManualObj(0)
  23. {}
  24. /************************************************************************/
  25. /* AI WORLD MANAGER DESTRUCTOR */
  26. /************************************************************************/
  27. AIWorldManager::~AIWorldManager()
  28. {
  29. this->destroyCrowds();
  30. }
  31. /************************************************************************/
  32. /* DESTROY CROWDS */
  33. /************************************************************************/
  34. void AIWorldManager::destroyCrowds()
  35. {
  36. dtCrowdHandler* crowdHandler = this->mCrowdsHandler, *nextCrowdHandler;
  37. while(crowdHandler)
  38. {
  39. //for( int i = 0 ; i < crowdHandler->getCrowd()->getAgentCount() ; i++)
  40. //{
  41. //
  42. // delete crowdHandler->getCrowd()->getAgent(i);
  43. //}
  44. //delete[] crowdHandler->getCrowd()->getAgent(0);
  45. nextCrowdHandler = crowdHandler->getNextCrowdHandler();
  46. delete crowdHandler;
  47. crowdHandler = nextCrowdHandler;
  48. }
  49. this->mCrowdsHandler = NULL;
  50. this->mCrowdsNo = 0;
  51. dtCrowd::resetStaticMembers();
  52. }
  53. /************************************************************************/
  54. /* INITIALIZE */
  55. /************************************************************************/
  56. void AIWorldManager::initialize()
  57. {
  58. staticObstacles = std::list<InputGeom*>();
  59. dynamicObstacle = std::list<InputGeom*>();
  60. // Initialize the parameters for building navigation mesh
  61. m_hasBuiltNaviMesh = false;
  62. m_cellSize = 0.3f;
  63. m_cellHeight = 0.2f;
  64. //m_agentHeight = 2.0f;
  65. m_agentRadius = 0.6f;
  66. m_agentMaxClimb = 0.9f;
  67. m_agentMaxSlope = 45.0f;
  68. m_regionMinSize = 8;
  69. m_regionMergeSize = 20;
  70. m_monotonePartitioning = false;
  71. m_edgeMaxLen = 12.0f;
  72. m_edgeMaxError = 1.3f;
  73. m_vertsPerPoly = 6.0f;
  74. m_detailSampleDist = 6.0f;
  75. m_detailSampleMaxError = 1.0f;
  76. m_debug = false;
  77. m_drawNaviMesh = false;
  78. mActiveSign = 0;
  79. }
  80. bool AIWorldManager::isDynamic(GameObject* gObj)
  81. {
  82. if(gObj->m_eObjectType == PHYSICS_FIXED )
  83. return false;
  84. else
  85. return true;
  86. }
  87. void AIWorldManager::TranslateMesh(Ogre::Vector3 pos,int index,GameObject* gObj, bool translateOrset)
  88. {
  89. if (index < 0) return;
  90. rcContext ctx;
  91. std::list<InputGeom*>::iterator it;
  92. if(isDynamic(gObj))
  93. {
  94. it = dynamicObstacle.begin();
  95. }
  96. else
  97. {
  98. it = staticObstacles.begin();
  99. }
  100. std::advance(it, index);
  101. const Ogre::MeshPtr cMeshPtr = gObj->m_pGraphicsObject->m_pOgreEntity->getMesh();
  102. Ogre::MeshPtr ptr = ((Ogre::MeshPtr)cMeshPtr);
  103. (*it)->setMeshTONull();
  104. if(!translateOrset)
  105. (*it)->setPosition(pos);
  106. else
  107. (*it)->setPosition((*it)->getPosition() + pos);
  108. (*it)->loadMesh(&ctx,ptr);
  109. if(mSample && isDynamic(gObj))
  110. mSample->updateTempObstacleNahid(index,(*it));
  111. }
  112. void AIWorldManager::OrientMesh(Ogre::Quaternion quad,int index,GameObject* gObj)
  113. {
  114. if (index < 0) return;
  115. rcContext ctx;
  116. std::list<InputGeom*>::iterator it;
  117. if(isDynamic(gObj))
  118. it = dynamicObstacle.begin();
  119. else
  120. it = staticObstacles.begin();
  121. std::advance(it, index);
  122. const Ogre::MeshPtr cMeshPtr = gObj->m_pGraphicsObject->m_pOgreEntity->getMesh();
  123. Ogre::MeshPtr ptr = ((Ogre::MeshPtr)cMeshPtr);
  124. (*it)->setMeshTONull();
  125. Ogre::Quaternion preOrient = (*it)->getOrient();
  126. (*it)->setOrient(preOrient * quad);
  127. (*it)->loadMesh(&ctx,ptr);
  128. if(mSample && isDynamic(gObj))
  129. mSample->updateTempObstacleNahid(index,(*it));
  130. }
  131. void AIWorldManager::ScaleMesh(Ogre::Vector3 scale,int index,GameObject* gObj)
  132. {
  133. if (index < 0) return;
  134. rcContext ctx;
  135. std::list<InputGeom*>::iterator it;
  136. if(isDynamic(gObj))
  137. it = dynamicObstacle.begin();
  138. else
  139. it = staticObstacles.begin();
  140. std::advance(it, index);
  141. const Ogre::MeshPtr cMeshPtr = gObj->m_pGraphicsObject->m_pOgreEntity->getMesh();
  142. Ogre::MeshPtr ptr = ((Ogre::MeshPtr)cMeshPtr);
  143. (*it)->setMeshTONull();
  144. Ogre::Vector3 preScale = (*it)->getScale();
  145. (*it)->setScale(preScale * scale);
  146. (*it)->loadMesh(&ctx,ptr);
  147. if(mSample && isDynamic(gObj))
  148. mSample->updateTempObstacleNahid(index,(*it));
  149. }
  150. void AIWorldManager::UpdateWorld(float dt)
  151. {
  152. if(this->mSample && this->m_hasBuiltNaviMesh)
  153. {
  154. this->mSample->handleUpdate(dt);
  155. if (this->mCrowdsHandler)
  156. {
  157. dtNavMesh* nav = this->mSample->getNavMesh();
  158. if (!nav) return;
  159. dtCrowdHandler* crowdHandler = this->mCrowdsHandler;
  160. while(crowdHandler)
  161. {
  162. crowdHandler->getCrowd()->update(dt, this->mSample, NULL);
  163. crowdHandler = crowdHandler->getNextCrowdHandler();
  164. }
  165. }
  166. }
  167. //Update the position of the active sign
  168. updateActiveSign();
  169. }
  170. void AIWorldManager::drawAgentPath()
  171. {
  172. dtAIAgent* agent;
  173. dtCrowd* crowd = this->getActiveCrowd();
  174. for(int i = 0 ; i < crowd->getAgentCount() ; i++)
  175. {
  176. if(crowd->getAgent(i)->isAgentActive())
  177. {
  178. agent = crowd->getAgent(i);
  179. agent->clearLines();
  180. NavMeshTesterTool* test = new NavMeshTesterTool;
  181. test->init(mSample);
  182. test->setStartPoint(agent->getAgentPositionV());
  183. if(agent->getAgentActiveTarget() != NULL)
  184. {
  185. Ogre::Vector3 targetPos = agent->getAgentActiveTarget()->getTargetPosV();
  186. test->setEndPoint(targetPos);
  187. test->handleMenu();
  188. Ogre::ManualObject* man = agent->addToLines();
  189. test->handleRender(man);
  190. }
  191. }
  192. }
  193. }
  194. void AIWorldManager::RenderWorld()
  195. {
  196. //return;
  197. if(this->mSample)
  198. {
  199. mManualObj->clear();
  200. this->mSample->handleRender(mManualObj, m_drawNaviMesh);
  201. dtNavMesh* nav = this->mSample->getNavMesh();
  202. if (!nav) return;
  203. dtCrowdHandler* crowdHandler = this->mCrowdsHandler;
  204. while(crowdHandler)
  205. {
  206. crowdHandler->getCrowd()->render();
  207. crowdHandler = crowdHandler->getNextCrowdHandler();
  208. }
  209. /*
  210. if(m_debug)
  211. this->drawAgentPath();
  212. else
  213. {
  214. if (this->mCrowdsNo)
  215. {
  216. dtAIAgent* agent;
  217. dtCrowd* crowd = this->getActiveCrowd();
  218. for(int i = 0 ; i < crowd->getAgentCount() ; i++)
  219. {
  220. if(crowd->getAgent(i)->isAgentActive())
  221. {
  222. agent = crowd->getAgent(i);
  223. agent->clearLines();
  224. }
  225. }
  226. }
  227. }
  228. */
  229. }
  230. }
  231. bool AIWorldManager::CreateStaticWorld()
  232. {
  233. std::list<InputGeom*>::iterator it;
  234. this->mSample = new Sample();
  235. // Set the parameters for building navigation mesh
  236. mSample->resetCommonSettings(m_cellSize, m_cellHeight, m_agentHeight, m_agentRadius, m_agentMaxClimb, m_agentMaxSlope,
  237. m_regionMinSize, m_regionMergeSize, m_monotonePartitioning, m_edgeMaxLen, m_edgeMaxError, m_vertsPerPoly,
  238. m_detailSampleDist, m_detailSampleMaxError );
  239. // TODO Fix case when there are no static objects
  240. if (staticObstacles.size() != 0)
  241. {
  242. rcContext ctx ;
  243. staticWorld = new InputGeom;
  244. for(it = staticObstacles.begin() ; it != staticObstacles.end(); it++)
  245. //TODO: combine should be fixed
  246. staticWorld->CombineInputGeoms((*it));
  247. staticWorld->SetBounds(&ctx);
  248. BuildContext ctx2;
  249. this->mSample->setContext(&ctx2);
  250. this->mSample->handleMeshChanged(staticWorld);
  251. this->mSample->handleSettings();
  252. this->mSample->handleBuild();
  253. }
  254. for(it = dynamicObstacle.begin() ; it != dynamicObstacle.end(); it++)
  255. this->mSample->addTempObstacle(Ogre::Vector3::ZERO,Ogre::Vector3::UNIT_SCALE, *it);
  256. Ogre::SceneManager *mSceneMgr = EnginePtr->GetForemostGameScreen()->GetDefaultSceneManager();
  257. mManualObj = mSceneMgr->createManualObject("manual");
  258. mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(mManualObj);
  259. // After nevi mesh is generated, the parameters cannot be changed afterwards
  260. m_hasBuiltNaviMesh = true;
  261. for(int i = 0 ; i < this->mCrowdsNo ; i++)
  262. {
  263. this->getCrowd(i)->InitNavQueryForPrevAgents(mSample->getNavMesh());
  264. for(int j = 0 ; j < this->getCrowd(i)->getAgentCount() ; j++)
  265. {
  266. if(this->getCrowd(i)->getAgent(j)->isAgentActive())
  267. this->getCrowd(i)->FindNearestPositionForPrevAgents(this->getCrowd(i)->getAgent(j));
  268. }
  269. }
  270. this->updateAgentHeight(-1,-1,true);
  271. return mSample->getInputGeom() != NULL;
  272. }
  273. void AIWorldManager::AddToWorld(GameObject* gObj)
  274. {
  275. //static
  276. if(!isDynamic(gObj))
  277. {
  278. rcContext* ctx = new rcContext();
  279. const Ogre::MeshPtr cMeshPtr = gObj->m_pGraphicsObject->m_pOgreEntity->getMesh();
  280. InputGeom* inputGeom = new InputGeom();
  281. Ogre::MeshPtr ptr = ((Ogre::MeshPtr)cMeshPtr);
  282. inputGeom->loadMesh(ctx,ptr);
  283. staticObstacles.push_back(inputGeom);
  284. gObj->indexInRecastWorld = staticObstacles.size() - 1;
  285. }
  286. else
  287. {
  288. rcContext* ctx = new rcContext();
  289. const Ogre::MeshPtr cMeshPtr = gObj->m_pGraphicsObject->m_pOgreEntity->getMesh();
  290. InputGeom* inputGeom = new InputGeom();
  291. Ogre::MeshPtr ptr = ((Ogre::MeshPtr)cMeshPtr);
  292. inputGeom->loadMesh(ctx,ptr);
  293. dynamicObstacle.push_back(inputGeom);
  294. gObj->indexInRecastWorld = dynamicObstacle.size() - 1;
  295. }
  296. //dynamic obstacle*/
  297. }
  298. void AIWorldManager::deleteWorld()
  299. {
  300. GamePipe::GameScreen* f_pCurrentGameScreen = EnginePtr->GetForemostGameScreen();
  301. GameObjectManager* f_pGameObjectManager = f_pCurrentGameScreen->GetGameObjectManager();
  302. //f_pGameObjectManager->DeleteGameObjects();
  303. destroyCrowds();
  304. delete mSample;
  305. for(list<InputGeom*>::iterator it = staticObstacles.begin();
  306. it != staticObstacles.end(); it++){
  307. delete *it;
  308. }
  309. for(list<InputGeom*>::iterator it = dynamicObstacle.begin();
  310. it != dynamicObstacle.end(); it++){
  311. delete *it;
  312. }
  313. }
  314. /************************************************************************/
  315. /* CROWD RELATED METHODS */
  316. /************************************************************************/
  317. dtCrowd * AIWorldManager::addNewCrowd( char *agentMaterial /*= "WhiteMaterial"*/, float agentRadius /*= 2.0f*/, float agentHeight /*= 2.0f*/ )
  318. {
  319. // Navigate to last crowd
  320. dtCrowdHandler* pCurrentCrowd = this->mCrowdsHandler;
  321. while (pCurrentCrowd && pCurrentCrowd->getNextCrowdHandler())
  322. pCurrentCrowd = pCurrentCrowd->getNextCrowdHandler();
  323. // Initialize new crowd
  324. dtCrowd* crowd = dtAllocCrowd();
  325. dtCrowdHandler* pCrowdHandler = new dtCrowdHandler(crowd);
  326. if (pCurrentCrowd)
  327. pCurrentCrowd->setNextCrowdHandler(pCrowdHandler);
  328. else
  329. this->mCrowdsHandler = pCrowdHandler;
  330. this->mActiveCrowdId = this->mCrowdsNo;
  331. if(this->mSample != NULL)
  332. crowd->init(this->mCrowdsNo++, MAX_CROWD_AGENTS, agentRadius, agentMaterial, this->mSample->getNavMesh());
  333. else
  334. crowd->init(this->mCrowdsNo++, MAX_CROWD_AGENTS, agentRadius, agentMaterial, NULL);
  335. return crowd;
  336. }
  337. /************************************************************************/
  338. /* AGENT RELATED METHODS */
  339. /************************************************************************/
  340. /************************************************************************/
  341. /* ADD NEW TARGET */
  342. /************************************************************************/
  343. dtTarget* AIWorldManager::addNewTarget( const float* hitpoint, Ogre::String behavior /*= "arrive"*/ )
  344. {
  345. if (!this->mSample)
  346. return NULL;
  347. InputGeom* geom = this->mSample->getInputGeom();
  348. if (!geom)
  349. return NULL;
  350. dtCrowd *crowd = this->getActiveCrowd();
  351. if (!crowd)
  352. return NULL;
  353. // Find nearest point on navmesh and set move request to that location.
  354. dtNavMeshQuery* navquery = this->mSample->getNavMeshQuery();
  355. const dtQueryFilter* filter = crowd->getFilter();
  356. const float* ext = crowd->getQueryExtents();
  357. float targetPos[3];
  358. dtPolyRef targetRef;
  359. navquery->findNearestPoly(hitpoint, ext, filter, &targetRef, targetPos);
  360. dtTarget* newTarget = NULL;
  361. // Add new target to path
  362. if (behavior == "follow_path")
  363. newTarget = crowd->addNewTarget(targetPos, targetRef);
  364. else if (behavior == "arrive") // Set a new target for seek and arrive behavior
  365. newTarget = crowd->setNewTarget(targetPos, targetRef);
  366. // Update target for agents
  367. for (int i = 0; i < crowd->getAgentCount(); ++i)
  368. {
  369. dtAIAgent* ag = crowd->getAgent(i);
  370. if (ag->isAgentActive() && (ag->isIdle() || (ag->hasPathFindingSteeringBehavior() && !ag->hasPursuitSteeringBehavior())))
  371. {
  372. // TODO Fix behavior when there is already a target
  373. if (behavior == "follow_path")
  374. ag->setPathFollowingSteeringBehavior(newTarget);
  375. else if (behavior == "arrive")
  376. ag->setSeekAndArriveSteeringBehavior(newTarget);
  377. }
  378. }
  379. if (behavior == "flee" && this->mActiveAgentId != -1)
  380. {
  381. this->getActiveAgent()->setFleeSteeringBehavior(new dtTarget(targetPos, targetRef));
  382. }
  383. return newTarget;
  384. }
  385. /************************************************************************/
  386. /* SET PURSUIT TARGET */
  387. /************************************************************************/
  388. void AIWorldManager::setPursuitTarget(int iTarget)
  389. {
  390. this->setPursuitTarget(this->getActiveCrowd()->getAgent(iTarget));
  391. }
  392. /************************************************************************/
  393. /* SET EVADE TARGET */
  394. /************************************************************************/
  395. void AIWorldManager::setEvadeTarget(int iTarget)
  396. {
  397. this->setEvadeTarget(this->getActiveCrowd()->getAgent(iTarget));
  398. }
  399. /************************************************************************/
  400. /* SET PURSUIT TARGET */
  401. /************************************************************************/
  402. void AIWorldManager::setPursuitTarget(dtAIAgent* target)
  403. {
  404. if (target && target->isAgentActive())
  405. this->getActiveAgent()->setPursuitSteeringBehavior(target);
  406. }
  407. /************************************************************************/
  408. /* SET EVADE TARGET */
  409. /************************************************************************/
  410. void AIWorldManager::setEvadeTarget(dtAIAgent* target)
  411. {
  412. if (target && target->isAgentActive())
  413. this->getActiveAgent()->setEvadeSteeringBehavior(target);
  414. }
  415. float AIWorldManager::CalcAgentRadius(float* bmin, float* bmax, dtCrowdAgentParams* ap)
  416. {
  417. //if (!this->mSample) return false;
  418. float radius = 0;
  419. float dx = bmax[0] - bmin[0];
  420. float dz = bmax[2] - bmin[2];
  421. if(radius < dx/2)
  422. {
  423. radius = dx / 2;
  424. ap->radiusXOrZ = true;
  425. }
  426. if(radius < dz/ 2)
  427. {
  428. radius = dz / 2;
  429. ap->radiusXOrZ = false;
  430. }
  431. ap->radius = radius;
  432. return radius;
  433. }
  434. /************************************************************************/
  435. /* ADD NEW AGENT */
  436. /************************************************************************/
  437. dtAIAgent* AIWorldManager::addNewAgent( const float* hitpoint, string meshName /*= ""*/, string hkxName /*= ""*/,string characterName /*= ""*/, char* luaFile /*= ""*/, Ogre::String behavior /*= "none"*/, char* type /*= "GRAPHICS_OBJECT"*/, GameObject* gobj )
  438. {
  439. //if (!this->mSample) return NULL;
  440. //InputGeom* geom = this->mSample->getInputGeom();
  441. //if (!geom) return NULL;
  442. dtCrowdHandler* crowdHandler = this->mCrowdsHandler;
  443. if (!crowdHandler || !crowdHandler->getCrowd())
  444. this->addNewCrowd();
  445. dtCrowd* crowd = this->getActiveCrowd();
  446. if(meshName == "")
  447. {
  448. meshName = "";
  449. hkxName = "";
  450. if ( type == "GRAPHICS_OBJECT" )
  451. {
  452. meshName = "Sinbad.mesh";
  453. hkxName = "";
  454. }
  455. else if ( type == "ANIMATED_CHARACTER_RIGIDBODY" )
  456. {
  457. #ifdef STORMTROOPER
  458. meshName = "stormtrooper_withgun_bound_LOD.mesh";
  459. hkxName = "storm_trooper_ragdoll_complete.hkx";
  460. #elif defined HAVOK_GIRL
  461. std::string meshName = "havokGirl3.mesh";
  462. std::string hkxName = "havokGirl3.hkx";
  463. #else
  464. meshName = "merc.mesh";
  465. hkxName = "merc.hkx";
  466. #endif
  467. }
  468. }
  469. //update the Radius , always set it to the maximum radius among agents in a crowd
  470. //------------------------------------------------------
  471. InputGeom* agentGeom = new InputGeom();
  472. rcContext* ctx = new rcContext();
  473. //Ogre::MeshManager* meshMn = Ogre::MeshManager.getSingletonPtr();
  474. Ogre::MeshPtr ptr = Ogre::MeshManager::getSingletonPtr()->load(meshName,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
  475. agentGeom->loadMesh(ctx,ptr);
  476. //crowd->setCrowdRadius(((float*)agentGeom->getMeshBoundsMin()),((float*)agentGeom->getMeshBoundsMax()));
  477. dtCrowdAgentParams ap;
  478. float agentRadius = CalcAgentRadius(((float*)agentGeom->getMeshBoundsMin()),((float*)agentGeom->getMeshBoundsMax()), &ap);
  479. //-------------------------------------------------------
  480. // Add
  481. memset(&ap, 0, sizeof(ap));
  482. //ap.radius = this->mSample->getAgentRadius();
  483. ap.radius = agentRadius;
  484. ap.height = agentGeom->getMeshBoundsMax()[1] - agentGeom->getMeshBoundsMin()[1];
  485. ap.maxAcceleration = 8;
  486. ap.maxSpeed = 3.5;
  487. //ap.collisionQueryRange = ap.radius * 12.0f;
  488. //ap.pathOptimizationRange = ap.radius * 30.0f;
  489. ap.collisionQueryRange = ap.radius * 12.0f;
  490. ap.pathOptimizationRange = ap.radius * 30.0f;
  491. ap.updateFlags = 0;
  492. ap.updateFlags |= DT_CROWD_ANTICIPATE_TURNS;
  493. ap.updateFlags |= DT_CROWD_OPTIMIZE_VIS;
  494. ap.updateFlags |= DT_CROWD_OPTIMIZE_TOPO;
  495. ap.updateFlags |= DT_CROWD_OBSTACLE_AVOIDANCE;
  496. ap.updateFlags |= DT_CROWD_SEPARATION;
  497. ap.obstacleAvoidanceType = (unsigned char) 3.0f;
  498. //THis may cuz the problem of getting too close
  499. ap.separationWeight = 1.5f;
  500. int idx = crowd->addAgent(hitpoint, &ap, crowd->getTargets(), type, meshName, hkxName, luaFile, characterName, gobj);
  501. //setting the m_agentHeight
  502. if(mSample != NULL && mSample->getAgentHeight() < ap.height)
  503. {
  504. mSample->setAgentHeight(ap.height);
  505. mSample->setAgentHeightIndex(idx);
  506. mSample->setAgentHeightCrowd(crowd->getCrowdID());
  507. }
  508. // Set agent physics parameters
  509. // Set agent behavior
  510. if (idx != -1)
  511. {
  512. if ((behavior == "arrive") || (behavior == "follow_path"))
  513. {
  514. dtTarget* target = crowd->getTargets();
  515. // Create agent with default behavior
  516. if (target)
  517. {
  518. if ((behavior == "follow_path") && target->getNextTarget() && target != target->getNextTarget())
  519. crowd->getAgent(idx)->setPathFollowingSteeringBehavior(target);
  520. else if (behavior == "arrive")
  521. crowd->getAgent(idx)->setSeekAndArriveSteeringBehavior(target);
  522. }
  523. }
  524. else if(behavior == "pursuit")
  525. crowd->getAgent(idx)->setPursuitSteeringBehavior(crowd->getAgent(0));
  526. else if(behavior == "evade")
  527. crowd->getAgent(idx)->setPursuitSteeringBehavior(crowd->getAgent(0));
  528. else if(behavior == "wander")
  529. crowd->getAgent(idx)->setWanderSteeringBehavior();
  530. }
  531. else
  532. return NULL;
  533. return crowd->getAgent(idx);
  534. }
  535. /************************************************************************/
  536. /* GET CROWD HANDLER */
  537. /************************************************************************/
  538. dtCrowdHandler* AIWorldManager::getCrowdHandler(int crowdID)
  539. {
  540. dtCrowdHandler* crowdHandler = this->mCrowdsHandler;
  541. while(crowdHandler)
  542. {
  543. if(crowdHandler->getCrowd()->getCrowdID() == crowdID)
  544. return crowdHandler;
  545. crowdHandler = crowdHandler->getNextCrowdHandler();
  546. }
  547. return NULL;
  548. }
  549. /************************************************************************/
  550. /* GET CROWD */
  551. /************************************************************************/
  552. dtCrowd* AIWorldManager::getCrowd(int crowdID)
  553. {
  554. dtCrowdHandler* crowdHandler = this->getCrowdHandler(crowdID);
  555. if (crowdHandler)
  556. return crowdHandler->getCrowd();
  557. return NULL;
  558. }
  559. void AIWorldManager::updateActiveSign( void )
  560. {
  561. if ( mActiveAgentId != -1 && mActiveSign )
  562. {
  563. dtAIAgent* ag = this->getActiveCrowd()->getAgent(mActiveAgentId);
  564. if (ag)
  565. {
  566. //Get the position of currently active agent
  567. float* pos = ag->getAgentPosition();
  568. float height = ag->getAgentParams()->height + 0.3f;
  569. //Set the active sign at the same place
  570. mActiveSign->setPosition(pos[0], pos[1] + height, pos[2]);
  571. }
  572. ag->setDebug(true, true);
  573. }
  574. }
  575. void AIWorldManager::setNaviParameters( float cellSize, float cellHeight, float agentHeight, float agentRadius,
  576. float agentMaxClimb, float agentMaxSlope, float regionMinSize, float regionMergeSize, bool monotonePartitioning,
  577. float edgeMaxLen, float edgeMaxError, float vertsPerPoly, float detailSampleDist, float detailSampleMaxError )
  578. {
  579. if ( m_hasBuiltNaviMesh == false )
  580. {
  581. m_cellSize = cellSize;
  582. m_cellHeight = cellHeight;
  583. m_agentHeight = agentHeight;
  584. m_agentRadius = agentRadius;
  585. m_agentMaxClimb = agentMaxClimb;
  586. m_agentMaxSlope = agentMaxSlope;
  587. m_regionMinSize = regionMinSize;
  588. m_regionMergeSize = regionMergeSize;
  589. m_monotonePartitioning = monotonePartitioning;
  590. m_edgeMaxLen = edgeMaxLen;
  591. m_edgeMaxError = edgeMaxError;
  592. m_vertsPerPoly = vertsPerPoly;
  593. m_detailSampleDist = detailSampleDist;
  594. m_detailSampleMaxError = detailSampleMaxError;
  595. }
  596. }
  597. void AIWorldManager::setActiveAgentPosition(const float* pos)
  598. {
  599. dtAIAgent* ag = this->getActiveCrowd()->getAgent(mActiveAgentId);
  600. if (ag && ag->isAgentActive())
  601. ag->setAgentPositionAbsolute(Ogre::Vector3(pos));
  602. }
  603. void AIWorldManager::updateAgentHeight(int m_agentID,int m_crowdID, bool checkAll)
  604. {
  605. if(checkAll || (mSample->getAgentHeightCrowd() == m_crowdID && mSample->getAgentHeightIndex() == m_agentID))
  606. {
  607. mSample->setAgentHeight(0);
  608. for(int i = 0 ; i < mCrowdsNo ; i++)
  609. {
  610. dtCrowd* temp = this->getCrowd(i);
  611. for(int j = 0 ; j < temp->getAgentCount() ; j++)
  612. {
  613. if(temp->getAgent(j)->getAgentParams()->height > mSample->getAgentHeight())
  614. {
  615. mSample->setAgentHeight(temp->getAgent(j)->getAgentParams()->height);
  616. mSample->setAgentHeightIndex(j);
  617. mSample->setAgentHeightCrowd(i);
  618. }
  619. }
  620. }
  621. this->updateDynamicObstacles();
  622. }
  623. }
  624. void AIWorldManager::updateDynamicObstacles()
  625. {
  626. if(!mSample)
  627. return;
  628. std::list<InputGeom*>::iterator it;
  629. int index = 0;
  630. for(it = dynamicObstacle.begin() ; it != dynamicObstacle.end(); it++)
  631. {
  632. mSample->updateTempObstacleNahid(index,*it);
  633. index++;
  634. }
  635. }
  636. std::string AIWorldManager::getNextAgentName(std::string prefix)
  637. {
  638. std::string name = prefix;
  639. int crowdID = this->getActiveCrowdId();
  640. int agentID = this->getActiveCrowd()->getActiveAgentsCount();
  641. std::ostringstream ID;
  642. ID<<crowdID<<"_"<<agentID;
  643. name += ID.str();
  644. return name;
  645. }