00001
00002
00003
00004
00005
00006 #include <netAspect.h>
00007 #include <ent.h>
00008 #include <engine.h>
00009
00010 void FastEcslent::NetAspect::init(){
00011 SPEED_TOLERANCE = 0.1;
00012 HEADING_TOLERANCE = 3.14159/360.0;
00013
00014 firstTick = true;
00015 pendingEntityId = -1;
00016 };
00017
00018 void FastEcslent::NetAspect::initNetworking(){
00019 int size = updateQueue.size();
00020 if(size > 0){
00021 statusData = *(updateQueue.back());
00022 this->clearQueue(&updateQueue, size);
00023
00024 remotePos = Ogre::Vector3(statusData.px,statusData.py,statusData.pz);
00025 entity->pos = remotePos;
00026
00027 entity->yaw = statusData.yaw;
00028 remoteVel = Ogre::Vector3(statusData.vx, statusData.vy, statusData.vz);
00029 entity->speed = remoteVel.length();
00030 entity->desiredSpeed = statusData.ds;
00031 entity->desiredHeading = statusData.dh;
00032 }
00033
00034 oldTime = 0;
00035 latency = 0;
00036 nSteps = 0;
00037
00038 ds = 0;
00039 dh = 0;
00040
00041 rotFactor = 0;
00042 rotProgress = 1.0;
00043
00044 if(entity->entityType == MINERALS){
00045 Minerals* mineral = dynamic_cast<Minerals*>(entity);
00046 if(mineral->mineralPatchId == 0){
00047 requestMineralPatchID();
00048 }
00049 }
00050 }
00051
00052 void FastEcslent::NetAspect::requestMineralPatchID(){
00053 entity->engine->net->requestMineralPatchID(entity->engine->net->getNetId(entity));
00054 }
00055
00056 void FastEcslent::NetAspect::tick(double dt){
00057 if(firstTick){
00058 initNetworking();
00059 firstTick = false;
00060 }
00061
00062 if(entity->ai->state == NETSLAVE){
00063 updateEcslent(dt);
00064 }else if(entity->ai->state == MANUAL && !entity->engine->options.isServer){
00065 updateServer(entity->desiredSpeed, entity->desiredHeading);
00066 }
00067
00068 if(this->checkPendingEntityId()){
00069 Entity* ent = this->entity->engine->net->getEntityFromNetId(pendingEntityId);
00070 setEntityBeingBuilt(this->entity->engine->net->getEntityFromNetId(pendingEntityId));
00071 }
00072 };
00073
00074 void FastEcslent::NetAspect::updateEcslent(double dt){
00075 int size = updateQueue.size();
00076 if(size > 0){
00077 statusData = *(updateQueue.back());
00078 this->clearQueue(&updateQueue, size);
00079
00080 nSteps = 0;
00081
00082 if(statusData.flag > oldTime){
00083 latency = (statusData.flag - oldTime)/1000.0;
00084 oldTime = statusData.flag;
00085 nSteps = latency/dt;
00086
00087 if(nSteps < 1){
00088 nSteps = 1;
00089 }
00090
00091 lerpPos();
00092 lerpRot();
00093 entity->desiredSpeed = statusData.ds;
00094 entity->desiredHeading = statusData.dh;
00095
00096 entity->hitpoints = statusData.hp;
00097 entity->timeLeftToBirth = statusData.timeLeftToBirth;
00098 }else{
00099 rotProgress = 0;
00100 nSteps = 0;
00101 }
00102
00103 if (nSteps > 0){
00104 entity->pos -= diffPosFrac;
00105 if(rotProgress< 1.0){
00106 qDelta = Ogre::Quaternion::Slerp(rotProgress, srcOrie, destOrie,true);
00107 deltaYaw = qDelta.getYaw().valueRadians();
00108 entity->yaw = deltaYaw;
00109 rotProgress += rotFactor;
00110 }
00111 nSteps -= 1;
00112 }
00113 }
00114 }
00115
00116 void FastEcslent::NetAspect::createEntity(EntityType entType, Ogre::Vector3 pos){
00117 entity->engine->net->createEntFromClientReq(this->entity->entityId.id, entType, pos);
00118 }
00119
00120 void FastEcslent::NetAspect::lerpPos(){
00121 remotePos = Ogre::Vector3(statusData.px, statusData.py, statusData.pz);
00122 remoteVel = Ogre::Vector3(statusData.vx, statusData.vy, statusData.vz);
00123 nextRemotePos = remotePos + (remoteVel * latency);
00124 nextPos = entity->pos + (entity->vel * latency);
00125 diffPos = nextPos - nextRemotePos;
00126 diffPosFrac = diffPos/nSteps;
00127 }
00128
00129 void FastEcslent::NetAspect::lerpRot(){
00130 remoteQuat = pitchYawRoll(0.0f, toDegrees(statusData.yaw), 0.0f);
00131 destOrie = remoteQuat * pitchYawRoll(0.0f, toDegrees(statusData.rSpeed * latency), 0.0f);
00132 srcOrie = pitchYawRoll(0.0, toDegrees(entity->yaw), 0.0f);
00133 finalDestOrie = destOrie * srcOrie;
00134 if(destOrie.equals(srcOrie, Ogre::Radian(HEADING_TOLERANCE))){
00135 rotFactor = 1.0;
00136 rotProgress = 1.0;
00137 }else{
00138 rotProgress = 1.0/nSteps;
00139 rotProgress = rotFactor;
00140 }
00141 }
00142
00143 bool FastEcslent::NetAspect::withinSpeedTolerance(float a, float b){
00144 return std::abs(a - b) < SPEED_TOLERANCE;
00145 }
00146
00147 bool FastEcslent::NetAspect::withinHeadingTolerance(float a, float b){
00148 return std::abs(a - b) < HEADING_TOLERANCE;
00149 }
00150
00151 void FastEcslent::NetAspect::updateServer(float newDS, float newDH){
00152 if(withinSpeedTolerance(ds,newDS) and withinHeadingTolerance(dh, newDH)){
00153 return;
00154 }else{
00155 ds = newDS;
00156 dh = newDH;
00157 if(dh >= -pi and dh <= pi and ds <= entity->maxSpeed and ds >=0){
00158 CommandEntity* cmd = new CommandEntity();
00159 cmd->id = entity->engine->net->getNetId(entity);
00160 cmd->ds = ds;
00161 cmd->dh = dh;
00162 SquelchEntity* squelch = new SquelchEntity();
00163 squelch->id = cmd->id;
00164 entity->engine->net->addCommand(cmd);
00165 entity->engine->net->addSquelch(squelch);
00166 }
00167 }
00168 }
00169
00170 bool FastEcslent::NetAspect::isValid(State *s){
00171 if(s->id == 0 && s->dh == 0 && s->ds == 0
00172 && s->px == 0 && s->py == 0 && s->pz == 0
00173 && s->vx == 0 && s->vy == 0 && s->vz==0)
00174 return false;
00175 else
00176 return true;
00177 }
00178
00179 void FastEcslent::NetAspect::squalch(){
00180 if(entity->ai){
00181 entity->ai->state = NETSLAVE;
00182 }
00183 }
00184
00185 void FastEcslent::NetAspect::squalchOtherClients(){
00186 if(entity->ai){
00187 entity->ai->state = NETSLAVE;
00188 }
00189 }
00190
00191 void FastEcslent::NetAspect::clearQueue(std::deque<State*> * queue, int size){
00192 for(int i=0; i< size; i++){
00193 State * s = queue->front();
00194 queue->pop_front();
00195 delete s;
00196 }
00197 }
00198
00199 void FastEcslent::NetAspect::setEntityBeingBuilt(int entId){
00200 this->pendingEntityId = entId;
00201 }
00202
00203 bool FastEcslent::NetAspect::checkPendingEntityId(){
00204
00205 if(this->entity->engine->net->getEntityFromNetId(pendingEntityId) != NULL){
00206 return true;
00207 }
00208 return false;
00209 }
00210
00211 void FastEcslent::NetAspect::setEntityBeingBuilt(Entity* ent){
00212
00213 if(this->entity->builder != NULL){
00214 this->entity->builder->entityBeingBuilt = ent;
00215 this->entity->builder->waitNetworkResponse = false;
00216 this->pendingEntityId = -1;
00217 }
00218 }