00001 /* 00002 * distance.cpp 00003 * 00004 * Created on: Jan 27, 2012 00005 * Author: sushil 00006 */ 00007 00008 #include <distanceMgr.h> 00009 #include <engine.h> 00010 #include <ent.h> 00011 #include <const.h> 00012 00013 #include <cfloat> 00014 #include "DEBUG.h" 00015 00016 //FastEcslent::DistanceMgr::DistanceMgr(){ 00017 //} 00018 00019 FastEcslent::DistanceMgr::DistanceMgr(Engine* eng, Options opts): Mgr (eng){ 00020 options = opts; 00021 //nEnts = 0; 00022 } 00023 00024 void FastEcslent::DistanceMgr::init(){ 00025 //nEnts = engine->entityMgr->nEnts; 00026 //ents = engine->entityMgr->ents; 00027 for(int i = 0; i < MaxEnts; i++){ 00028 collisions[i] = 0; 00029 closestEnemy[i] = -1; 00030 closestEnemyDistance[i] = DBL_MAX; 00031 furthestEnt[i] = -1; 00032 furthestDistance[i] = 0; 00033 00034 } 00035 collisionTotal = 0; 00036 //DEBUG(std::cout << "Distance Manager: " << nEnts << " number of ents in game" << std::endl;) 00037 00038 } 00039 00040 00041 00042 float FastEcslent::DistanceMgr::cpaTime(const Entity *ent1, const Entity *ent2){ 00043 Ogre::Vector3 dv = ent1->vel - ent2->vel; 00044 float dvDotdv = dv.dotProduct(dv); 00045 if (dvDotdv < FastEcslent::EPSILON) { 00046 return 0.0; 00047 } 00048 Ogre::Vector3 w0 = ent1->pos - ent2->pos; 00049 return w0.dotProduct(dv)/dvDotdv; 00050 } 00051 00052 float FastEcslent::DistanceMgr::cpaSquaredDistance(const Entity *ent1, const Entity *ent2){ 00053 float cpaT = cpaTime(ent1, ent2); 00054 Ogre::Vector3 p1 = ent1->pos + (ent1->vel * cpaT); 00055 Ogre::Vector3 p2 = ent2->pos + (ent2->vel * cpaT); 00056 return p1.squaredDistance(p2); 00057 } 00058 00059 void FastEcslent::DistanceMgr::tick (double dt){ 00060 00061 for (int i = 0; i < engine->entityMgr->nEnts; i++){ 00062 ent = engine->entityMgr->ents[i]; 00063 distance[i][i] = 0.0; 00064 distanceVec[i][i] = Ogre::Vector3(0.0, 0.0, 0.0); 00065 00066 //need calculate closestEnemyDistance each frame 00067 closestEnemyDistance[i] = DBL_MAX; 00068 00069 for (int j = i+1; j < engine->entityMgr->nEnts; j++){ 00070 other = engine->entityMgr->ents[j]; 00071 00072 //ignore self 00073 if(other->entityId.id == ent->entityId.id){ 00074 continue; 00075 } 00076 //if the saved entity is dead, reset the distance information. 00077 if(other->entityState != FastEcslent::ALIVE && closestEnemy[i] == j){ 00078 closestEnemy[i] = -1; 00079 closestEnemyDistance[i] = DBL_MAX; 00080 furthestEnt[i] = -1; 00081 furthestDistance[i] = 0; 00082 return; 00083 } 00084 00085 distanceVec[i][j] = other->pos - ent->pos; 00086 normalizedDistanceVec[i][j] = distanceVec[i][j].normalisedCopy(); 00087 distanceVec[j][i] = ent->pos - other->pos; 00088 normalizedDistanceVec[j][i] = distanceVec[j][i].normalisedCopy(); 00089 distance[i][j] = distanceVec[i][j].length(); 00090 distance[j][i] = distance[i][j]; 00091 /* if(distance[i][j] < (ent->length + other->length)*2){ 00092 collisions[i]++; 00093 collisions[j]++; 00094 collisionTotal++; 00095 }*/ 00096 //if(distance[i][j] < closestEnemyDistance[i] && other->alive && other->entityId.side != ent->entityId.side){ 00097 if(distance[i][j] < closestEnemyDistance[i] && other->entityState == FastEcslent::ALIVE && other->entityId.side != ent->entityId.side){ 00098 closestEnemyDistance[i] = distance[i][j]; 00099 closestEnemy[i] = j; 00100 00101 } 00102 //if(distance[j][i] < closestEnemyDistance[j] && ent->alive && other->entityId.side != ent->entityId.side){ 00103 if(distance[j][i] < closestEnemyDistance[j] && ent->entityState == FastEcslent::ALIVE && other->entityId.side != ent->entityId.side){ 00104 closestEnemyDistance[j] = distance[j][i]; 00105 closestEnemy[j] = i; 00106 } 00107 if(distance[i][j] > furthestDistance[i]){ 00108 furthestDistance[i] = distance[i][j]; 00109 furthestEnt[i] = j; 00110 } 00111 if(distance[j][i] > furthestDistance[j]){ 00112 furthestDistance[j] = distance[j][i]; 00113 furthestEnt[j] = i; 00114 } 00115 cpa[i][j].cpaTime = cpaTime(ent, other); 00116 cpa[j][i].cpaTime = cpa[i][j].cpaTime; 00117 cpa[i][j].cpaSquaredDistance = cpaSquaredDistance(ent, other); 00118 cpa[j][i].cpaTime = cpa[i][j].cpaSquaredDistance; 00119 00120 } 00121 } 00122 } 00123 00124 void FastEcslent::DistanceMgr::dumpAll (){ 00125 for (int i = 0; i < engine->entityMgr->nEnts; i++){ 00126 dumpOne(i); 00127 } 00128 } 00129 00130 void FastEcslent::DistanceMgr::dumpOne (int index){ 00131 //Entity *ent = engine->entityMgr->ents[index]; 00132 for (int j = 0; j < engine->entityMgr->nEnts; j++){ 00133 //if (j == index) continue; 00134 // DEBUG(std::cout << "Distance from ent: " << ent->entityId.id << " to " << ents[j]->entityId.id << " is " << distance[index][j] << std::endl;) 00135 DEBUG(std::cout << distance[index][j] << ", ";) 00136 } 00137 DEBUG(std::cout << std::endl;) 00138 } 00139 00140