#include <TeamUnits.h>
Collaboration diagram for ASR::TeamUnits:
Public Types | |
typedef vector< Unit * > | UnitList |
typedef VectorIterator< UnitList > | UnitIterator |
Public Member Functions | |
TeamUnits (Team *parentTeam, unsigned int initialUnits=0) | |
~TeamUnits () | |
void | findTargets () |
Unit * | createUnit (String meshName) |
void | moveUnits (float deltaTime) |
void | animateUnits (float deltaTime) |
UnitIterator | getUnitIterator () |
Unit * | getUnit (size_t index) |
size_t | getNumUnits () |
void | performAttacks () |
void | setSpatialGridSize (int numBucketsWide, int numBucketsHigh) |
UnitList | getAdjacentUnits (const Vector3 &worldPos, float radius) |
Returns a list of Units within the given radius of the specified world position. | |
void | updateSpatialGrid () |
Updates the spatial information of each unit inside of the grid. | |
Private Types | |
typedef vector< UnitList > | SpatialColumn |
typedef vector< SpatialColumn > | SpatialGrid |
Private Member Functions | |
void | _clearSpatialGrid () |
Removes all units from the grid but does not change the size. | |
Private Attributes | |
SceneNode * | mTeamNode |
RaySceneQuery * | mRaySceneQuery |
UnitList | mUnits |
Team * | mTeam |
SpatialGrid | mUnitGrid |
Static Private Attributes | |
static int | mNumTeams = 0 |
Definition at line 29 of file TeamUnits.h.
typedef vector<UnitList> ASR::TeamUnits::SpatialColumn [private] |
Definition at line 52 of file TeamUnits.h.
typedef vector<SpatialColumn> ASR::TeamUnits::SpatialGrid [private] |
Definition at line 53 of file TeamUnits.h.
typedef VectorIterator<UnitList> ASR::TeamUnits::UnitIterator |
Definition at line 35 of file TeamUnits.h.
typedef vector<Unit*> ASR::TeamUnits::UnitList |
Definition at line 34 of file TeamUnits.h.
ASR::TeamUnits::TeamUnits | ( | Team * | parentTeam, | |
unsigned int | initialUnits = 0 | |||
) |
Definition at line 43 of file TeamUnits.cpp.
References ASR::Team::getName(), ASR::Game::getSceneManager(), ASR::Game::getSingletonPtr(), mRaySceneQuery, mTeamNode, and mUnits.
00044 : mTeam ( parentTeam ) 00045 { 00046 // TODO 00047 // Create this on the Team SceneNode, not the Root SceneNode 00048 SceneManager* sceneMgr = Game::getSingletonPtr ()->getSceneManager (); 00049 mTeamNode = sceneMgr->getRootSceneNode()->createChildSceneNode( parentTeam->getName () ); 00050 00051 mRaySceneQuery = sceneMgr->createRayQuery( Ray() ); 00052 00053 mUnits.reserve ( initialUnits ); 00054 }
ASR::TeamUnits::~TeamUnits | ( | ) |
Definition at line 58 of file TeamUnits.cpp.
References ASR::Game::getSceneManager(), ASR::Game::getSingletonPtr(), mRaySceneQuery, and mUnits.
00059 { 00060 UnitList::iterator iter = mUnits.begin (); 00061 while ( iter != mUnits.end() ) 00062 { 00063 delete (*iter); 00064 iter++; 00065 } 00066 00067 SceneManager* sceneMgr = Game::getSingletonPtr ()->getSceneManager (); 00068 sceneMgr->destroyQuery ( mRaySceneQuery ); 00069 }
void ASR::TeamUnits::_clearSpatialGrid | ( | ) | [private] |
Removes all units from the grid but does not change the size.
Definition at line 305 of file TeamUnits.cpp.
References mUnitGrid.
Referenced by updateSpatialGrid().
00306 { 00307 for ( size_t i = 0; i < mUnitGrid.size(); i++ ) 00308 { 00309 for ( size_t j = 0; j < mUnitGrid[i].size(); j++ ) 00310 { 00311 mUnitGrid[i][j].clear (); 00312 } 00313 } 00314 }
void ASR::TeamUnits::animateUnits | ( | float | deltaTime | ) |
Definition at line 182 of file TeamUnits.cpp.
References mUnits.
Referenced by ASR::TeamUpdater::updateBeforeFrame().
00183 { 00184 // Apply all animations 00185 UnitList::iterator iter; 00186 for ( iter = mUnits.begin(); iter != mUnits.end(); iter++ ) 00187 { 00188 (*iter)->updateAnimation ( deltaTime ); 00189 } 00190 }
Unit * ASR::TeamUnits::createUnit | ( | String | meshName | ) |
Definition at line 73 of file TeamUnits.cpp.
References mTeamNode, and mUnits.
Referenced by ASR::Team::createUnit().
00074 { 00075 Unit* newUnit = new Unit ( mTeamNode, meshName ); 00076 00077 mUnits.push_back ( newUnit ); 00078 00079 return newUnit; 00080 }
void ASR::TeamUnits::findTargets | ( | ) |
Definition at line 194 of file TeamUnits.cpp.
References ASR::Level::getEnemyTeams(), ASR::Level::getSingleton(), getUnitIterator(), and mTeam.
Referenced by ASR::TeamUpdater::updateAfterFrame().
00195 { 00196 // TODO 00197 // Use the spatial grid to make this search a lot faster 00198 00199 // Grab a list of the enemy teams 00200 Level::TeamList enemyTeams = Level::getSingleton ().getEnemyTeams ( mTeam ); 00201 00202 // For each unit 00203 // If the unit already has a target, move on to the next unit 00204 // Grab a list of adjacent enemy units 00205 // Loop through and find the best target (for now, the closest) 00206 // Assign the target 00207 // Notify the target of attack 00208 UnitIterator iter = getUnitIterator (); 00209 while ( iter.hasMoreElements () ) 00210 { 00211 Unit* curUnit = iter.getNext (); 00212 if ( curUnit->isEngaged() || curUnit->isDead () ) 00213 continue; 00214 00215 UnitList allEnemies; 00216 Level::TeamIterator curEnemyTeam ( enemyTeams.begin(), enemyTeams.end() ); 00217 00218 while ( curEnemyTeam.hasMoreElements () ) 00219 { 00220 Team* enemy = curEnemyTeam.getNext (); 00221 UnitList unitList = enemy->getAdjacentUnits ( curUnit->getPosition(), curUnit->getSightRadius () ); 00222 allEnemies.insert ( allEnemies.end(), unitList.begin(), unitList.end() ); 00223 } 00224 00225 // Determine the closest unit to us 00226 float distance = Math::POS_INFINITY; 00227 Unit* bestTarget = NULL; 00228 00229 UnitIterator secondIter ( allEnemies.begin(), allEnemies.end() ); 00230 while ( secondIter.hasMoreElements () ) 00231 { 00232 Unit* enemyUnit = secondIter.getNext (); 00233 00234 if ( enemyUnit->isDead() ) 00235 continue; 00236 00237 Vector3 targetLine = enemyUnit->getPosition () - curUnit->getPosition (); 00238 if ( targetLine.length() < distance ) 00239 { 00240 bestTarget = enemyUnit; 00241 distance = targetLine.length(); 00242 } 00243 } 00244 00245 if ( distance <= curUnit->getSightRadius () ) 00246 curUnit->assignTarget ( bestTarget ); 00247 } 00248 }
TeamUnits::UnitList ASR::TeamUnits::getAdjacentUnits | ( | const Vector3 & | worldPos, | |
float | radius | |||
) |
Returns a list of Units within the given radius of the specified world position.
This is only an approximation and may return units further than 'radius' units away. This is just a very fast prune technique.
Definition at line 318 of file TeamUnits.cpp.
References ASR::Level::getNumNodesHigh(), ASR::Level::getNumNodesWide(), ASR::Level::getSingleton(), ASR::Level::getWorldHeight(), ASR::Level::getWorldWidth(), and mUnitGrid.
Referenced by ASR::Team::getAdjacentUnits().
00319 { 00320 // TODO 00321 // Take the radius into account 00322 // 00323 // Possibly return a list of indices in a vector that can be used 00324 // to obtain a reference to the internal list that's store (const) 00325 // so that we don't build a huge unit list each and every frame 00326 00327 UnitList units; 00328 00329 int worldWidth = Level::getSingleton ().getWorldWidth (); 00330 int worldHeight = Level::getSingleton ().getWorldHeight (); 00331 00332 unsigned int cellWidth = worldWidth / mUnitGrid.size (); 00333 unsigned int cellHeight = worldHeight / mUnitGrid[0].size(); 00334 00335 unsigned int cellX = worldPos.x / cellWidth; 00336 unsigned int cellZ = worldPos.z / cellHeight; 00337 00338 if ( cellX >= mUnitGrid.size () || cellZ >= mUnitGrid[cellX].size() ) 00339 throw Exception ( Exception::ERR_INVALIDPARAMS, "World position is outside of grid", "TeamUnits::getAdjacentUnits" ); 00340 00341 if ( cellX < 0 || cellZ < 0 ) 00342 throw Exception ( Exception::ERR_INVALIDPARAMS, "World position is outside of grid", "TeamUnits::getAdjacentUnits" ); 00343 00344 // Add all Units in the current list as well as all neighbouring lists 00345 units = mUnitGrid[cellX][cellZ]; 00346 00347 OgreAssert ( Level::getSingleton().getNumNodesWide(), "Must have at least one node width" ); 00348 OgreAssert ( Level::getSingleton().getNumNodesHigh(), "Must have at least one node height" ); 00349 00350 unsigned int cellsWide = Level::getSingleton ().getNumNodesWide () - 1; 00351 unsigned int cellsHigh = Level::getSingleton ().getNumNodesHigh () - 1; 00352 00353 00354 // Top-left 00355 if ( cellX > 0 && cellZ > 0 ) 00356 units.insert ( units.end(), mUnitGrid[cellX - 1][cellZ - 1].begin(), mUnitGrid[cellX - 1][cellZ - 1].end () ); 00357 // Bottom-left 00358 if ( cellX > 0 && cellZ < cellsWide ) 00359 units.insert ( units.end(), mUnitGrid[cellX - 1][cellZ + 1].begin(), mUnitGrid[cellX - 1][cellZ + 1].end () ); 00360 // Middle-left 00361 if ( cellX > 0 ) 00362 units.insert ( units.end(), mUnitGrid[cellX - 1][cellZ].begin(), mUnitGrid[cellX - 1][cellZ].end () ); 00363 // Top-right 00364 if ( cellX < cellsWide && cellZ > 0 ) 00365 units.insert ( units.end(), mUnitGrid[cellX + 1][cellZ - 1].begin(), mUnitGrid[cellX + 1][cellZ - 1].end () ); 00366 // Bottom-right 00367 if ( cellX < cellsWide && cellZ < cellsWide ) 00368 units.insert ( units.end(), mUnitGrid[cellX + 1][cellZ + 1].begin(), mUnitGrid[cellX + 1][cellZ + 1].end () ); 00369 // Middle-right 00370 if ( cellX < cellsWide ) 00371 units.insert ( units.end(), mUnitGrid[cellX + 1][cellZ].begin(), mUnitGrid[cellX + 1][cellZ].end () ); 00372 // Top-middle 00373 if ( cellZ > 0 ) 00374 units.insert ( units.end(), mUnitGrid[cellX][cellZ - 1].begin(), mUnitGrid[cellX][cellZ - 1].end () ); 00375 // Bottom-middle 00376 if ( cellZ < cellsHigh ) 00377 units.insert ( units.end(), mUnitGrid[cellX][cellZ + 1].begin(), mUnitGrid[cellX][cellZ + 1].end () ); 00378 00379 return units; 00380 }
size_t ASR::TeamUnits::getNumUnits | ( | ) |
Definition at line 94 of file TeamUnits.cpp.
References mUnits.
00095 { 00096 return mUnits.size(); 00097 }
Unit * ASR::TeamUnits::getUnit | ( | size_t | index | ) |
Definition at line 84 of file TeamUnits.cpp.
References mUnits.
Referenced by ASR::TeamUpdater::updateAfterFrame().
00085 { 00086 if ( index >= mUnits.size() ) 00087 throw Exception ( Exception::ERR_ITEM_NOT_FOUND, "Unit index to high", "TeamUnits::GetUnit" ); 00088 00089 return mUnits[index]; 00090 }
TeamUnits::UnitIterator ASR::TeamUnits::getUnitIterator | ( | ) |
Definition at line 252 of file TeamUnits.cpp.
References mUnits.
Referenced by findTargets(), ASR::Team::findTargets(), ASR::Team::getUnitIterator(), performAttacks(), and updateSpatialGrid().
00253 { 00254 return UnitIterator ( mUnits.begin(), mUnits.end() ); 00255 }
void ASR::TeamUnits::moveUnits | ( | float | deltaTime | ) |
Definition at line 101 of file TeamUnits.cpp.
References mRaySceneQuery, mUnits, and ASR::UNIT_SPEED.
Referenced by ASR::TeamUpdater::updateBeforeFrame().
00102 { 00103 // Move all the units, keeping them on the terrain 00104 UnitList::iterator unitIter; 00105 Vector3 nodePos; 00106 00107 for ( unitIter = mUnits.begin(); unitIter != mUnits.end(); unitIter++ ) 00108 { 00109 // Update the Unit to move towards any destination if it has one 00110 if ( (*unitIter)->hasDestination () ) 00111 { 00112 Vector3 destPos = (*unitIter)->getDestination(); 00113 Vector3 srcPos = (*unitIter)->getPosition (); 00114 destPos.y = srcPos.y; 00115 00116 // See if we reached the current destination 00117 Vector3 diff = destPos - srcPos; 00118 00119 if ( diff.isZeroLength() ) 00120 { 00121 // Move on to the next waypoint 00122 (*unitIter)->setPosition ( destPos ); 00123 (*unitIter)->removeDestination (); 00124 } 00125 else 00126 { 00127 // Update the position 00128 Vector3 translation = diff.normalisedCopy(); 00129 translation = translation * (deltaTime * UNIT_SPEED); 00130 00131 // Check if they hit the destination and if so, snap them 00132 00133 // TODO 00134 // Use the left over movement to go to the next waypoint 00135 if ( translation.length() > diff.length() ) 00136 { 00137 (*unitIter)->setPosition( destPos ); 00138 (*unitIter)->removeDestination(); 00139 } 00140 else 00141 { 00142 (*unitIter)->translate ( Vector3(translation.x, 0.0, translation.z), Node::TS_WORLD ); 00143 } 00144 } 00145 00146 /* 00147 (*unitIter)->getEntity()->getAnimationState ( "Idle" )->setEnabled( false ); 00148 (*unitIter)->getEntity()->getAnimationState ( "Walk" )->setEnabled( true ); 00149 (*unitIter)->getEntity()->getAnimationState ( "Walk" )->addTime ( deltaTime ); 00150 */ 00151 } 00152 else 00153 { 00154 /* 00155 (*unitIter)->getEntity()->getAnimationState ( "Idle" )->setEnabled( true ); 00156 (*unitIter)->getEntity()->getAnimationState ( "Idle" )->addTime ( deltaTime ); 00157 (*unitIter)->getEntity()->getAnimationState ( "Walk" )->setEnabled( false ); 00158 */ 00159 } 00160 00161 nodePos = (*unitIter)->getPosition (); 00162 00163 // Setup the query 00164 Ray unitRay ( Vector3( nodePos.x, 5000.0f, nodePos.z ), Vector3::NEGATIVE_UNIT_Y ); 00165 mRaySceneQuery->setRay ( unitRay ); 00166 00167 // Perform the query 00168 RaySceneQueryResult& result = mRaySceneQuery->execute (); 00169 RaySceneQueryResult::iterator iter = result.begin(); 00170 00171 // Use the query 00172 if ( iter != result.end() && iter->worldFragment ) 00173 { 00174 Real terrainHeight = iter->worldFragment->singleIntersection.y; 00175 (*unitIter)->setPosition ( Vector3((*unitIter)->getPosition().x, terrainHeight, (*unitIter)->getPosition().z )); 00176 } 00177 } 00178 }
void ASR::TeamUnits::performAttacks | ( | ) |
Definition at line 384 of file TeamUnits.cpp.
References getUnitIterator().
Referenced by ASR::TeamUpdater::updateAfterFrame().
00385 { 00386 UnitIterator iter = getUnitIterator (); 00387 while ( iter.hasMoreElements () ) 00388 { 00389 Unit* curUnit = iter.getNext (); 00390 //if ( curUnit->isEngaged () ) 00391 curUnit->doAttack (); 00392 } 00393 }
void ASR::TeamUnits::setSpatialGridSize | ( | int | numBucketsWide, | |
int | numBucketsHigh | |||
) |
Definition at line 259 of file TeamUnits.cpp.
References mUnitGrid.
Referenced by ASR::Team::Team().
00260 { 00261 // Erase the old grid 00262 // TODO 00263 // Do we need to go through and erase each column? 00264 mUnitGrid.clear (); 00265 00266 for ( int i = 0; i < numBucketsWide; i++ ) 00267 { 00268 SpatialColumn col; 00269 col.resize ( numBucketsHigh ); 00270 mUnitGrid.push_back ( col ); 00271 } 00272 }
void ASR::TeamUnits::updateSpatialGrid | ( | ) |
Updates the spatial information of each unit inside of the grid.
Definition at line 276 of file TeamUnits.cpp.
References _clearSpatialGrid(), ASR::Level::getSingleton(), getUnitIterator(), ASR::Level::getWorldHeight(), ASR::Level::getWorldWidth(), and mUnitGrid.
Referenced by ASR::TeamUpdater::updateBeforeFrame().
00277 { 00278 // TODO 00279 // Instead of clearing this every frame, use the movement of 00280 // the Unit to determine if it crosses the boundaries of a cell 00281 // and then remove it from it's current grid cell and put it 00282 // in the new grid cell 00283 _clearSpatialGrid (); 00284 00285 int worldWidth = Level::getSingleton ().getWorldWidth (); 00286 int worldHeight = Level::getSingleton ().getWorldHeight (); 00287 00288 unsigned int cellWidth = worldWidth / mUnitGrid.size (); 00289 unsigned int cellHeight = worldHeight / mUnitGrid[0].size(); 00290 00291 UnitIterator iter = getUnitIterator (); 00292 while ( iter.hasMoreElements () ) 00293 { 00294 Unit* curUnit = iter.getNext (); 00295 00296 unsigned int cellX = curUnit->getPosition ().x / cellWidth; 00297 unsigned int cellZ = curUnit->getPosition ().z / cellHeight; 00298 00299 mUnitGrid[cellX][cellZ].push_back ( curUnit ); 00300 } 00301 }
int ASR::TeamUnits::mNumTeams = 0 [static, private] |
Definition at line 45 of file TeamUnits.h.
RaySceneQuery* ASR::TeamUnits::mRaySceneQuery [private] |
Definition at line 41 of file TeamUnits.h.
Referenced by moveUnits(), TeamUnits(), and ~TeamUnits().
Team* ASR::TeamUnits::mTeam [private] |
SceneNode* ASR::TeamUnits::mTeamNode [private] |
SpatialGrid ASR::TeamUnits::mUnitGrid [private] |
Definition at line 54 of file TeamUnits.h.
Referenced by _clearSpatialGrid(), getAdjacentUnits(), setSpatialGridSize(), and updateSpatialGrid().
UnitList ASR::TeamUnits::mUnits [private] |
Definition at line 43 of file TeamUnits.h.
Referenced by animateUnits(), createUnit(), getNumUnits(), getUnit(), getUnitIterator(), moveUnits(), TeamUnits(), and ~TeamUnits().