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 };
00016
00017 void FastEcslent::NetAspect::initNetworking(){
00018 int size = updateQueue.size();
00019 if(size > 0){
00020 statusData = *(updateQueue.back());
00021 this->clearQueue(&updateQueue, size);
00022
00023 remotePos = Ogre::Vector3(statusData.px,statusData.py,statusData.pz);
00024 entity->pos = remotePos;
00025
00026 entity->yaw = statusData.yaw;
00027 remoteVel = Ogre::Vector3(statusData.vx, statusData.vy, statusData.vz);
00028 entity->speed = remoteVel.length();
00029 entity->desiredSpeed = statusData.ds;
00030 entity->desiredHeading = statusData.dh;
00031 }
00032
00033 oldTime = 0;
00034 latency = 0;
00035 nSteps = 0;
00036
00037 ds = 0;
00038 dh = 0;
00039
00040 rotFactor = 0;
00041 rotProgress = 1.0;
00042 }
00043
00044
00045
00046 void FastEcslent::NetAspect::tick(double dt){
00047 if(firstTick){
00048 initNetworking();
00049 firstTick = false;
00050 }
00051
00052 if(entity->ai->state == NETSLAVE){
00053 updateEcslent(dt);
00054 }else if(entity->ai->state == MANUAL && !entity->engine->options.isServer){
00055 updateServer(entity->desiredSpeed, entity->desiredHeading);
00056 }
00057 };
00058
00059 void FastEcslent::NetAspect::updateEcslent(double dt){
00060 int size = updateQueue.size();
00061 if(size > 0){
00062 statusData = *(updateQueue.back());
00063 this->clearQueue(&updateQueue, size);
00064
00065 nSteps = 0;
00066
00067 if(statusData.flag > oldTime){
00068 latency = (statusData.flag - oldTime)/1000.0;
00069 oldTime = statusData.flag;
00070 nSteps = latency/dt;
00071
00072 lerpPos();
00073 lerpRot();
00074 entity->desiredSpeed = statusData.ds;
00075 entity->desiredHeading = statusData.dh;
00076 }else{
00077 rotProgress = 0;
00078 nSteps = 0;
00079 }
00080
00081 if (nSteps > 0){
00082 entity->pos -= diffPosFrac;
00083 if(rotProgress< 1.0){
00084 qDelta = Ogre::Quaternion::Slerp(rotProgress, srcOrie, destOrie,true);
00085 deltaYaw = qDelta.getYaw().valueRadians();
00086 entity->yaw = deltaYaw;
00087 rotProgress += rotFactor;
00088 }
00089 nSteps -= 1;
00090 }
00091 }
00092 }
00093
00094 void FastEcslent::NetAspect::lerpPos(){
00095 remotePos = Ogre::Vector3(statusData.px, statusData.py, statusData.pz);
00096 remoteVel = Ogre::Vector3(statusData.vx, statusData.vy, statusData.vz);
00097 nextRemotePos = remotePos + (remoteVel * latency);
00098 nextPos = entity->pos + (entity->vel * latency);
00099 diffPos = nextPos - nextRemotePos;
00100 diffPosFrac = diffPos/nSteps;
00101 }
00102
00103 void FastEcslent::NetAspect::lerpRot(){
00104 remoteQuat = pitchYawRoll(0.0f, toDegrees(statusData.yaw), 0.0f);
00105 destOrie = remoteQuat * pitchYawRoll(0.0f, toDegrees(statusData.rSpeed * latency), 0.0f);
00106 srcOrie = pitchYawRoll(0.0, toDegrees(entity->yaw), 0.0f);
00107 finalDestOrie = destOrie * srcOrie;
00108 if(destOrie.equals(srcOrie, Ogre::Radian(HEADING_TOLERANCE))){
00109 rotFactor = 1.0;
00110 rotProgress = 1.0;
00111 }else{
00112 rotProgress = 1.0/nSteps;
00113 rotProgress = rotFactor;
00114 }
00115 }
00116
00117 bool FastEcslent::NetAspect::withinSpeedTolerance(float a, float b){
00118 return std::abs(a - b) < SPEED_TOLERANCE;
00119 }
00120
00121 bool FastEcslent::NetAspect::withinHeadingTolerance(float a, float b){
00122 return std::abs(a - b) < HEADING_TOLERANCE;
00123 }
00124
00125 void FastEcslent::NetAspect::updateServer(float newDS, float newDH){
00126 if(withinSpeedTolerance(ds,newDS) and withinHeadingTolerance(dh, newDH)){
00127 return;
00128 }else{
00129 ds = newDS;
00130 dh = newDH;
00131 if(dh >= -pi and dh <= pi and ds <= entity->maxSpeed and ds >=0){
00132 CommandEntity* cmd = new CommandEntity();
00133 cmd->id = entity->engine->net->getNetId(entity);
00134 cmd->ds = ds;
00135 cmd->dh = dh;
00136 SquelchEntity* squelch = new SquelchEntity();
00137 squelch->id = cmd->id;
00138 entity->engine->net->addCommand(cmd);
00139 entity->engine->net->addSquelch(squelch);
00140 }
00141 }
00142 }
00143
00144 bool FastEcslent::NetAspect::isValid(State *s){
00145 if(s->id == 0 && s->dh == 0 && s->ds == 0
00146 && s->px == 0 && s->py == 0 && s->pz == 0
00147 && s->vx == 0 && s->vy == 0 && s->vz==0)
00148 return false;
00149 else
00150 return true;
00151 }
00152
00153 void FastEcslent::NetAspect::squalch(){
00154 if(entity->ai){
00155 entity->ai->state = NETSLAVE;
00156 }
00157 }
00158
00159 void FastEcslent::NetAspect::squalchOtherClients(){
00160 if(entity->ai){
00161 entity->ai->state = NETSLAVE;
00162 }
00163 }
00164
00165 void FastEcslent::NetAspect::clearQueue(std::deque<State*> * queue, int size){
00166 for(int i=0; i< size; i++){
00167 State * s = queue->front();
00168 queue->pop_front();
00169 delete s;
00170 }
00171 }