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
00115
00116
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
00146
00147
00148
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
00179
00180
00181
00182
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
00193
00194
00195
00196
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
00227 if ( Math::Abs(mForward.x) >= Math::Abs(mForward.z) )
00228 mForward.y = mForward.z = 0.0f;
00229
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 }