command.cpp

Go to the documentation of this file.
00001 /*
00002  * command.cpp
00003  *
00004  *  Created on: Jan 9, 2012
00005  *      Author: sushil
00006  */
00007 
00008 #include <const.h>
00009 #include <ent.h>
00010 #include <group.h>
00011 #include <target.h>
00012 #include <engine.h>
00013 #include <OgreVector3.h>
00014 #include "DEBUG.h"
00015 
00016 
00017 //#include <command.h>
00018 inline bool FastEcslent::Move::done() {
00019         return (entity->pos.squaredDistance((target->location)) <= entity->turningRadius);
00020 }
00021 
00022 void FastEcslent::Move::init(){
00023         Ogre::Vector3 diff = target->location - entity->pos;
00024         entity->desiredHeading = -atan2(diff.z, diff.x);
00025         entity->desiredSpeed = entity->maxSpeed;
00026         return;
00027 }
00028 
00029 inline void FastEcslent::Move::tick(double dt) {
00030         if(!done()) {
00031                 relativePos = target->location - entity->pos;
00032                 entity->desiredHeading = -atan2(relativePos.z, relativePos.x);
00033                 entity->desiredSpeed = entity->maxSpeed;
00034         } else {
00035                 entity->desiredSpeed = 0.0f;
00036         }
00037         return;
00038 }
00039 //Gather for SCV
00040 //------------------------------------------------------------------------------------------
00041 inline void FastEcslent::Wait::init(){
00042         timeLeftToWait = target->waitTime;
00043 
00044 }
00045 inline bool FastEcslent::Wait::done(){
00046         return timeLeftToWait < 0.0;
00047 }
00048 
00049 inline void FastEcslent::Wait::tick(double dt){
00050         if(timeLeftToWait > 0) {
00051                 timeLeftToWait -= dt;
00052         } else {
00053                 DEBUG(std::cout << entity->uiname  << ": Done waiting" << std::endl;)
00054         }
00055 }
00056 //------------------------------------------------------------------------------------------
00057 
00058 
00059 // Potential fields move for groups
00060 
00061 inline bool FastEcslent::PotentialMove::done(){
00062         //preturn false;
00063         return (entity->pos.squaredDistance(target->location) <= (entity->turningRadius * entity->turningRadius)*10.0);// && (int) ((entity->attractivePotential)) > -15);
00064 }
00065 
00066 void FastEcslent::PotentialMove::init(){
00067         Ogre::Vector3 diff = target->location - entity->pos;
00068         entity->desiredSpeed = entity->maxSpeed;
00069 
00070 }
00071 
00072 inline void FastEcslent::PotentialMove::tick(double dt){
00073         int nEnts = entity->engine->entityMgr->nEnts;
00074 
00075         if (!done()){
00076                 // compute force
00077                         double repulsivePotential = 0.0f;
00078                         entity->potentialVec = Ogre::Vector3::ZERO;
00079                         Ogre::Vector3 tmp;
00080                         int nInRange = 1; // at least one so that you don't multiply by 0 later
00081                         for (int i = 0; i < nEnts; i++){
00082                                 if(i != entity->entityId.id){// repulsed by all other entities
00083                                         if (entity->engine->distanceMgr->distance[entity->entityId.id][i] < RepulsionThresholdDistance) { // Don't care about entities too far away
00084                                                 nInRange += 1;
00085                                                 tmp = (entity->engine->distanceMgr->normalizedDistanceVec[i][entity->entityId.id]);
00086                                                 repulsivePotential =  (B * entity->engine->entityMgr->ents[i]->mass) / pow(entity->engine->distanceMgr->distance[entity->entityId.id][i], m);
00087                                                 entity->potentialVec += (tmp * repulsivePotential);
00088                                         }
00089                                 }
00090                         }
00091                         //attracted by target
00092 
00093                         tmp = (entity->pos - target->location);
00094                         //tmp = target->location - entity->pos;
00095                         double targetDistance = tmp.length();
00096                         entity->attractivePotential =  -(A ) / pow(targetDistance, n);// + (B) /pow (targetDistance, m);
00097                         entity->potentialVec += (tmp.normalisedCopy() * entity->attractivePotential * nInRange); // nInRange needs to be at least 1
00098 
00099                         //applyPotential(entity, potentialVec);
00100 
00101                         entity->desiredHeading = atan2(-entity->potentialVec.z, entity->potentialVec.x);
00102                         double cosDiffFrac = (1.0 - cos(entity->vel.angleBetween(entity->potentialVec).valueRadians()))/2.0;// between 0 and 2 divided by 2.0 gives something between 0 and 1
00103                         entity->desiredSpeed   = (entity->maxSpeed - entity->minSpeed) * (1.0 - cosDiffFrac);
00104 
00105 
00106 
00107                 // apply force
00108         } else {
00109                 DEBUG(std::cout << "Attractive Potential: " << entity->attractivePotential << std::endl;)
00110                 entity->desiredSpeed = 0.0f;
00111                 entity->desiredHeading = entity->heading;
00112         }
00113 }
00114 
00115 
00116 
00117 
00118 FastEcslent::Maintain::Maintain (Entity *ent, Target *tgt): UnitCommand(ent, MaintainCommand, tgt){
00119         if(valid(tgt->entity)) {
00120                 DEBUG(std::cout << "Maintaining with respect to: " << tgt->entity->uiname << std::endl;)
00121                 tgt->location = tgt->entity->pos + tgt->offset;
00122         }
00123 }
00124 bool FastEcslent::Maintain::valid(Entity *entity) {
00125         return true;
00126 }
00127 
00128 inline bool FastEcslent::Maintain::done() {
00129         return false;
00130 }
00131 
00132 void FastEcslent::Maintain::init(){
00133 
00134         if (kInvalidFloat == target->offsetDistance) { // offset must contain absolute position right now. Convert to offsetRot and offsetDistance
00135                 Ogre::Quaternion q = Ogre::Vector3(cos(-target->entity->heading) * 100.0f, 0.0f, sin(-target->entity->heading) * 100.0f).getRotationTo(target->offset);
00136                 target->offsetYaw = q.getYaw().valueRadians();
00137                 target->offsetDistance = (target->entity->pos - target->offset).length();
00138                 DEBUG(std::cout << "OffsetYaw: " << target->offsetYaw << " offsetDistance: " << target->offsetDistance << std::endl;)
00139         }
00140         return;
00141 }
00142 
00143 inline void FastEcslent::Maintain::tick(double dt) { //offsetRotation and offsetDistance set by init()
00144         target->offset = (target->entity->rot * Ogre::Quaternion(Ogre::Radian(target->offsetYaw), Ogre::Vector3::UNIT_Y)) * (Ogre::Vector3::UNIT_X * target->offsetDistance);
00145         target->location = target->entity->pos + target->offset;
00146 
00147         relativePos = target->location - entity->pos;
00148         relativeVel = target->entity->vel - entity->vel;
00149         relativeSpeed = relativeVel.length();
00150         predictedTimeToClose = relativePos.length()/relativeSpeed;
00151         predictedPos =  target->location + (target->entity->vel * predictedTimeToClose);
00152         interceptPos = predictedPos - entity->pos;
00153 
00154         entity->desiredHeading = -atan2(interceptPos.z, interceptPos.x);
00155         if ((relativeSpeed * predictedTimeToClose) > 30)
00156                 entity->desiredSpeed = entity->maxSpeed;
00157         else
00158                 entity->desiredSpeed = target->entity->speed;
00159 
00160         return;
00161 }
00162 
00163 
00164 void FastEcslent::Tactic::changeLeadership(LeadershipType selector){
00165 
00166         Ogre::Vector3 tpos;
00167         if(this->target->target.location == InvalidLocation){
00168                 tpos = this->target->target.entity->pos;
00169         } else {
00170                 tpos = this->target->target.location;
00171         }
00172         this->group->leaderIndex = 0;
00173         if (this->group->nEntitiesInGroup > 0) {
00174                 switch(selector){
00175                 case 0:
00176                         this->group->leaderIndex = closestToTarget(true, tpos);
00177                         break;
00178                 case 2:
00179                         this->group->leaderIndex = closestToTarget(false, tpos); //furthest from target
00180                         break;
00181                 case 3:
00182                         this->group->leaderIndex = mostMassive(true);
00183                         break;
00184                 case 4:
00185                         this->group->leaderIndex = mostMassive(true);//smallest mass
00186                         break;
00187                 case 5:
00188                         this->group->leaderIndex = randInt(0, this->group->nEntitiesInGroup);
00189                         break;
00190                 default:
00191                         this->group->leaderIndex = 0;
00192                         break;
00193                 }
00194         }
00195 
00196 }
00197 
00198 
00199 int FastEcslent::Tactic::mostMassive(bool massest){
00200         float minMass = 0;
00201         int minIndex = INT_MAX;
00202         float maxMass = 0;
00203         int maxIndex = 0;
00204         float mass;
00205         for (int i = 0; i < this->group->nEntitiesInGroup; i++){
00206                 mass = this->group->members[i]->mass;
00207                 if(mass < minMass){
00208                         minMass = mass;
00209                         minIndex = i;
00210                 }
00211                 if (mass > maxMass){
00212                         maxMass = mass;
00213                         maxIndex = i;
00214                 }
00215         }
00216         if(!massest) {
00217                 return minIndex;
00218         } else {
00219                 return maxIndex;
00220         }
00221 
00222 }
00223 
00224 
00225 int FastEcslent::Tactic::closestToTarget(bool closest, Ogre::Vector3 tpos){
00226         //Entity** members = this->group->members;
00227                 //int dist = members[leaderIndex]->pos.distance(this->target->target.location);
00228 
00229         float minDist = 0;
00230         int minIndex = INT_MAX;
00231         float maxDist = 0;
00232         int maxIndex = 0;
00233         float dist;
00234         for (int i = 0; i < this->group->nEntitiesInGroup; i++){
00235                 dist = this->group->members[i]->pos.distance(tpos);
00236                 if(dist < minDist) {
00237                         minDist = dist;
00238                         minIndex = i;
00239                 }
00240                 if (dist > maxDist){
00241                         maxDist = dist;
00242                         maxIndex = i;
00243                 }
00244         }
00245         if(closest) {
00246                 return minIndex;
00247         } else {
00248                 return maxIndex;
00249         }
00250 }

Generated on Fri Dec 13 14:54:17 2013 for FastECSLent by  doxygen 1.5.4