D:/simple_rts/src/ControlGroup.cpp

Go to the documentation of this file.
00001 #include "ControlGroup.h"
00002 
00003 #include "Unit.h"
00004 #include "LineFormation.h"
00005 
00006 #include "OgreException.h"
00007 #include "OgreMath.h"
00008 
00009 #include <cassert>
00010 
00011 using Ogre::Exception;
00012 using Ogre::Math;
00013 
00014 namespace ASR
00015 {
00016         // ----------------------------------------------------------------------------
00017         ControlGroup::ControlGroup ()
00018                 : mForward ( Vector3::ZERO ), mRight ( Vector3::ZERO )
00019         {
00020                 mCurFormation = new LineFormation ();
00021                 mUnits.clear ();
00022                 mDirty = false;
00023         }
00024 
00025 
00026         // ----------------------------------------------------------------------------
00027         ControlGroup::~ControlGroup ()
00028         {
00029                 delete mCurFormation;
00030                 mUnits.clear ();
00031         }
00032 
00033 
00034         // ----------------------------------------------------------------------------
00035         int ControlGroup::addUnit ( Unit* unit )
00036         {
00037                 mUnits.push_back ( unit );
00038                 mDirty = true;
00039                 return mUnits.size() - 1;
00040         }
00041 
00042 
00043         // ----------------------------------------------------------------------------
00044         void ControlGroup::removeUnit ( size_t index )
00045         {
00046                 assert ( index < mUnits.size() && index <= 0 );
00047                 UnitList::iterator iter = mUnits.begin();
00048                 
00049                 for ( size_t i = 0; i < index; i++ )
00050                 {
00051                         iter++;
00052                 }
00053 
00054                 mUnits.erase ( iter );
00055                 mDirty = true;
00056         }
00057 
00058 
00059         // ----------------------------------------------------------------------------
00060         void ControlGroup::removeUnit ( Unit* unit )
00061         {
00062                 UnitList::iterator iter = find ( mUnits.begin(), mUnits.end(), unit );
00063                 if ( iter == mUnits.end () )
00064                         throw Exception ( Exception::ERR_ITEM_NOT_FOUND, "Unit not found", "ControlGroup::removeUnit" );
00065 
00066                 mUnits.erase ( iter );
00067                 mDirty = true;
00068         }
00069 
00070 
00071         // ----------------------------------------------------------------------------
00072         Vector3 ControlGroup::getFormationCenter ()
00073         {
00074                 if ( mDirty )
00075                         _updateFormation ();
00076 
00077                 return mFormationCenter;
00078         }
00079 
00080 
00081         // ----------------------------------------------------------------------------
00082         void ControlGroup::_updateFormation ()
00083         {
00084                 _calcCenter ();
00085                 _calcOrientation ();
00086 
00087                 mDirty = false;
00088         }
00089 
00090 
00091         // ----------------------------------------------------------------------------
00092         void ControlGroup::_calcCenter ()
00093         {
00094                 UnitList::iterator iter;
00095                 Vector3 total = Vector3::ZERO;
00096 
00097                 if ( mUnits.size () == 0 )
00098                         return;
00099 
00100                 for ( iter = mUnits.begin(); iter != mUnits.end(); iter++ )
00101                 {
00102                         total += Vector3( (*iter)->getPosition ().x, 0.0f, (*iter)->getPosition ().z );
00103                 }
00104 
00105                 mFormationCenter = total / mUnits.size();
00106         }
00107 
00108 
00109         // ----------------------------------------------------------------------------
00110         Vector3 ControlGroup::getUnitOffset ( Unit* unit )
00111         {
00112                 int index = getUnitIndex ( unit );
00113 
00114                 // TODO
00115                 //              Ask the Formation for the offset
00116                 //              Currently just returning a huge line
00117                 int position;
00118                 if ( index % 2 == 0 )
00119                         position = index / 2;
00120                 else
00121                         int position = -( index + 1 ) / 2;
00122 
00123                 Vector3 singleOffset ( 0, 0, 10 );
00124                 Vector3 localPos = getFormationCenter () + ( singleOffset * position );
00125                 return localPos;
00126         }
00127 
00128 
00129         // ----------------------------------------------------------------------------
00130         int ControlGroup::getUnitIndex ( Unit* unit )
00131         {
00132                 for ( size_t i = 0; i < mUnits.size(); i++ )
00133                 {
00134                         if ( mUnits[i] == unit )
00135                                 return i;
00136                 }
00137 
00138                 throw Exception ( Exception::ERR_ITEM_NOT_FOUND, "Unit not found", "ControlGroup::getUnitIndex" );
00139         }
00140 
00141 
00142         // ----------------------------------------------------------------------------
00143         void ControlGroup::setDestination ( const Vector3& dest )
00144         {
00145                 // TODO
00146                 //      Figure out a path for each and every unit in this list
00147                 //      using their offsets. We just move each unit as close
00148                 //      to where it is supposed to be as possible
00149                 mDestination = dest;
00150         }
00151 
00152 
00153         // ----------------------------------------------------------------------------
00154         Unit* ControlGroup::getLeaderUnit ()
00155         {
00156                 assert ( !mUnits.empty() );
00157                 return mUnits[0];
00158         }
00159 
00160 
00161         // ----------------------------------------------------------------------------
00162         Vector3 ControlGroup::getUnitDestination ( Unit* unit )
00163         {
00164                 if ( mDirty )
00165                         _updateFormation ();
00166 
00167                 int index = getUnitIndex ( unit );
00168 
00169                 return getUnitDestination ( index );
00170         }
00171 
00172 
00173         // ----------------------------------------------------------------------------
00174         Vector3 ControlGroup::getUnitDestination ( int index )
00175         {
00176                 OgreAssert ( index < mUnits.size (), "Unit index out of bounds" );
00177 
00178                 //update ();
00179 
00180                 // TODO
00181                 //              Ask the Formation for the offset
00182                 //              Currently just returning a huge line
00183                 int xPos;
00184                 if ( (index % 5) % 2 == 0 )
00185                         xPos = (index % 5) / 2;
00186                 else
00187                         xPos = -( (index % 5) + 1 ) / 2;
00188 
00189                 int zPos;
00190                 zPos = -(index / 5);
00191 
00192                 // TODO
00193                 //              Take the orientation of the ControlGroup into account
00194                 //              Use the "right" vector as well as the negated "forward"
00195                 //              vector (mOrientation)
00196                 //              Possibly snap to 90° rotations ala Starcraft
00197                 Vector3 xOffset = mRight * 30;
00198                 Vector3 zOffset = mForward * 30;
00199 
00200                 Vector3 localPos = mDestination + ( xOffset * xPos ) + ( zOffset * zPos );
00201                 return localPos;
00202         }
00203 
00204 
00205         // ----------------------------------------------------------------------------
00206         Unit* ControlGroup::getUnit ( int index )
00207         {
00208                 OgreAssert ( index < mUnits.size (), "Unit index out of bounds" );
00209                 return mUnits[index];
00210         }
00211 
00212 
00213         // ----------------------------------------------------------------------------
00214         size_t ControlGroup::getNumUnits ()
00215         {
00216                 return mUnits.size();
00217         }
00218 
00219 
00220         // ----------------------------------------------------------------------------
00221         void ControlGroup::_calcOrientation ()
00222         {
00223                 mForward = mDestination - mFormationCenter;
00224                 mForward.normalise ();
00225 
00226                 // X-axis heavy
00227                 if ( Math::Abs(mForward.x) >= Math::Abs(mForward.z) )
00228                         mForward.y = mForward.z = 0.0f;
00229                 // Z-axis heavy
00230                 else
00231                         mForward.y = mForward.x = 0.0f;
00232 
00233                 mForward.normalise ();
00234         
00235                 mRight = mForward.crossProduct ( -Vector3::UNIT_Y );
00236                 mRight.normalise ();
00237         }
00238 
00239 
00240         // ----------------------------------------------------------------------------
00241         void ControlGroup::update ()
00242         {
00243                 _calcCenter ();
00244                 _calcOrientation ();
00245         }
00246 }

Generated on Sun Jun 25 19:23:43 2006 for Valors End by  doxygen 1.4.7