ASR::TeamUnits Class Reference

#include <TeamUnits.h>

Collaboration diagram for ASR::TeamUnits:

Collaboration graph
[legend]
List of all members.

Public Types

typedef vector< Unit * > UnitList
typedef VectorIterator< UnitListUnitIterator

Public Member Functions

 TeamUnits (Team *parentTeam, unsigned int initialUnits=0)
 ~TeamUnits ()
void findTargets ()
UnitcreateUnit (String meshName)
void moveUnits (float deltaTime)
void animateUnits (float deltaTime)
UnitIterator getUnitIterator ()
UnitgetUnit (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< UnitListSpatialColumn
typedef vector< SpatialColumnSpatialGrid

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
TeammTeam
SpatialGrid mUnitGrid

Static Private Attributes

static int mNumTeams = 0

Detailed Description

Definition at line 29 of file TeamUnits.h.


Member Typedef Documentation

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.


Constructor & Destructor Documentation

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         }


Member Function Documentation

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         }


Member Data Documentation

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]

Definition at line 46 of file TeamUnits.h.

Referenced by findTargets().

SceneNode* ASR::TeamUnits::mTeamNode [private]

Definition at line 40 of file TeamUnits.h.

Referenced by createUnit(), and TeamUnits().

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().


The documentation for this class was generated from the following files:
Generated on Sun Jun 25 19:23:44 2006 for Valors End by  doxygen 1.4.7