src/tron/zone/zShape.cpp

Go to the documentation of this file.
00001 #include "zShape.hpp"
00002 #include "gCycle.h"
00003 #include "zZone.h"
00004 
00005 zShape::zShape(eGrid* grid, unsigned short idZone)
00006         :eNetGameObject( grid, eCoord(0,0), eCoord(0,0), NULL, true ),
00007         posx_(),
00008         posy_(),
00009         scale_(),
00010         rotation2(),
00011         color_(),
00012         createdtime_(0.0),
00013         referencetime_(0.0),
00014         lasttime_(0.0),
00015         idZone_(idZone),
00016         newIdZone_(false)
00017 {
00018     joinWithZone();
00019 }
00020 
00021 zShape::zShape(nMessage &m):eNetGameObject(m)
00022 {
00023     REAL time;
00024     m >> time;
00025     setCreatedTime(time);
00026 
00027     networkRead(m);
00028 
00029     unsigned short anIdZone;
00030     m >> anIdZone;
00031     if(anIdZone != idZone_) {
00032         idZone_ = anIdZone;
00033         newIdZone_ = true;
00034         joinWithZone();
00035     }
00036 }
00037 
00038 
00039 void zShape::setCreatedTime(REAL time)
00040 {
00041     createdtime_ = time;
00042 
00043     // Usefull when the nMessage creates the zone in the middle of a round
00044     if(lasttime_ < createdtime_)
00045         lasttime_ = createdtime_;
00046 }
00047 
00048 void zShape::setReferenceTime(REAL time)
00049 {
00050     referencetime_ = time;
00051     // Do not update lasttime_, referencetime_ might be set in the future for ease of equation writing.
00052 }
00053 
00054 void zShape::networkWrite(nMessage &m)
00055 {
00056 
00057     m << referencetime_;
00058     m << posx_;
00059     m << posy_;
00060     m << scale_;
00061     m << rotation2;
00062     m << color_.r_;
00063     m << color_.g_;
00064     m << color_.b_;
00065     m << color_.a_;
00066 }
00067 
00068 void zShape::networkRead(nMessage &m)
00069 {
00070     REAL time;
00071     m >> time;
00072     setReferenceTime(time);
00073     m >> posx_;
00074     m >> posy_;
00075     m >> scale_;
00076     m >> rotation2;
00077 
00078     m >> color_.r_;
00079     m >> color_.g_;
00080     m >> color_.b_;
00081     m >> color_.a_;
00082 }
00083 
00084 /*
00085  * to create a shape on the clients
00086  */
00087 void zShape::WriteCreate( nMessage & m )
00088 {
00089     eNetGameObject::WriteCreate(m);
00090 
00091     m << createdtime_;
00092 
00093     networkWrite(m);
00094 
00095     m << idZone_;
00096 }
00097 
00098 void zShape::WriteSync(nMessage &m)
00099 {
00100     networkWrite(m);
00101 }
00102 
00103 void zShape::ReadSync(nMessage &m)
00104 {
00105     networkRead(m);
00106 }
00107 
00108 void zShape::setPosX(const tFunction & x){
00109     posx_ = x;
00110 }
00111 
00112 void zShape::setPosY(const tFunction & y){
00113     posy_ = y;
00114 }
00115 
00116 void zShape::setRotation2(const tPolynomial<nMessage> & r) {
00117   if(rotation2 == r) {
00118     // Empty: Nothing to do, no need to send an update
00119   }
00120   else {
00121     rotation2 = r;
00122     if (sn_GetNetState()!=nCLIENT)
00123         RequestSync();
00124   }
00125 }
00126 
00127 void zShape::setScale(const tFunction & s){
00128     scale_ = s;
00129 }
00130 
00131 void zShape::setColor(const rColor &c){
00132     if(color_ != c) {
00133         color_ = c;
00134         if (sn_GetNetState()!=nCLIENT)
00135             RequestSync();
00136     }
00137 }
00138 
00139 void zShape::setColorNow(const rColor &c){
00140     // TODO: make color slide with some fancy tFunc or something.
00141     setColor(c);
00142 }
00143 
00144 void zShape::animate( REAL time ) {
00145     // Is this needed as the items are already animated?
00146 }
00147 
00148 void zShape::TimeStep( REAL time ) {
00149     lasttime_ = time;
00150     /*
00151     REAL scale = scale_.Evaluate(lasttime_ - referencetime_);
00152     if (scale < -1.0) // Allow shapes to keep existing for a while even though they are not physical
00153       {
00154         // The shape has collapsed and should be removed
00155       }
00156     */
00157 
00158     if(newIdZone_) {
00159         joinWithZone();
00160     }
00161 
00162 }
00163 
00164 bool zShape::isInteracting(eGameObject * target) {
00165     return false;
00166 }
00167 
00168 void zShape::render(const eCamera *cam )
00169 {}
00170 void zShape::render2d(tCoord scale) const
00171     {}
00172 
00173 void zShape::joinWithZone() {
00174     if(sn_netObjects[idZone_]) {
00175         zZone *asdf = dynamic_cast<zZone*>(&*sn_netObjects[idZone_]);
00176         asdf->setShape(zShapePtr(this));
00177         newIdZone_ = false;
00178     }
00179 }
00180 
00181 zShapeCircle::zShapeCircle(eGrid *grid, unsigned short idZone):
00182         zShape(grid, idZone),
00183         emulatingOldZone_(false),
00184         radius(1.0, 0.0)
00185 {}
00186 
00187 zShapeCircle::zShapeCircle(nMessage &m):
00188         zShape(m),
00189         emulatingOldZone_(false),
00190         radius(1.0, 0.0)
00191 {
00192     m >> radius;
00193 }
00194 
00195 /*
00196  * to create a shape on the clients
00197  */
00198 void zShapeCircle::WriteCreate( nMessage & m )
00199 {
00200     zShape::WriteCreate(m);
00201 
00202     m << radius;
00203 }
00204 
00205 void zShapeCircle::WriteSync(nMessage &m)
00206 {
00207     zShape::WriteSync(m);
00208     m << radius;
00209 }
00210 
00211 void zShapeCircle::ReadSync(nMessage &m)
00212 {
00213     zShape::ReadSync(m);
00214     m >> radius;
00215 }
00216 
00217 bool zShapeCircle::isInteracting(eGameObject * target)
00218 {
00219     bool interact = false;
00220     gCycle* prey = dynamic_cast< gCycle* >( target );
00221     if ( prey )
00222     {
00223         if ( prey->Player() && prey->Alive() )
00224         {
00225             REAL effectiveRadius;
00226             effectiveRadius = scale_.Evaluate(lasttime_ - referencetime_) * radius.Evaluate(lasttime_ - referencetime_);
00227             // Is the player inside or outside the zone
00228             if ( (effectiveRadius >= 0.0) && ( prey->Position() - Position() ).NormSquared() < effectiveRadius*effectiveRadius )
00229             {
00230                 interact = true;
00231             }
00232         }
00233     }
00234     return interact;
00235 }
00236 
00237 void zShapeCircle::render(const eCamera * cam )
00238 {
00239 #ifndef DEDICATED
00240 
00241     // HACK
00242     int sg_segments = 11;
00243     bool sr_alphaBlend = true;
00244     // HACK
00245 
00246     if ( color_.a_ > .7f )
00247         color_.a_ = .7f;
00248     if ( color_.a_ <= 0 )
00249         return;
00250 
00251     REAL currAngle = rotation2.evaluate(lasttime_);
00252     eCoord rot( cos(currAngle), sin(currAngle) );
00253 
00254     GLfloat m[4][4]={{rot.x,rot.y,0,0},
00255                      {-rot.y,rot.x,0,0},
00256                      {0,0,1,0},
00257                      {posx_.Evaluate(lasttime_ - referencetime_), posy_.Evaluate(lasttime_ - referencetime_), 0,1}};
00258 
00259     ModelMatrix();
00260     glPushMatrix();
00261 
00262     glDisable(GL_LIGHT0);
00263     glDisable(GL_LIGHT1);
00264     glDisable(GL_LIGHTING);
00265     glDisable(GL_CULL_FACE);
00266     glBlendFunc( GL_SRC_ALPHA, GL_ONE );
00267 
00268     //glDisable(GL_TEXTURE);
00269     glDisable(GL_TEXTURE_2D);
00270 
00271     //  glTranslatef(pos.x,pos.y,0);
00272 
00273     glMultMatrixf(&m[0][0]);
00274     //  glScalef(.5,.5,.5);
00275 
00276     if ( sr_alphaBlend ) {
00277         glDepthMask(GL_FALSE);
00278         BeginQuads();
00279     } else {
00280         glDepthMask(GL_TRUE);
00281         BeginLineStrip();
00282     }
00283 
00284     const REAL seglen = .2f;
00285     const REAL bot = 0.0f;
00286     const REAL top = 5.0f; // + ( lastTime - referenceTime_ ) * .1f;
00287 
00288     color_.Apply();
00289 
00290     REAL effectiveRadius;
00291     effectiveRadius = scale_.Evaluate(lasttime_ - referencetime_) * radius.Evaluate(lasttime_ - referencetime_);
00292     if (effectiveRadius >= 0.0)
00293     {
00294         for ( int i = sg_segments - 1; i>=0; --i )
00295         {
00296             REAL a = i * 2 * 3.14159 / REAL( sg_segments );
00297             REAL b = a + seglen;
00298 
00299             REAL sa = effectiveRadius * sin(a);
00300             REAL ca = effectiveRadius * cos(a);
00301             REAL sb = effectiveRadius * sin(b);
00302             REAL cb = effectiveRadius * cos(b);
00303 
00304             glVertex3f(sa, ca, bot);
00305             glVertex3f(sa, ca, top);
00306             glVertex3f(sb, cb, top);
00307             glVertex3f(sb, cb, bot);
00308 
00309             if ( !sr_alphaBlend )
00310             {
00311                 glVertex3f(sa, ca, bot);
00312                 RenderEnd();
00313                 BeginLineStrip();
00314             }
00315         }
00316     }
00317 
00318     RenderEnd();
00319 
00320     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00321     glDepthMask(GL_TRUE);
00322 
00323     glPopMatrix();
00324 #endif
00325 
00326 }
00327 
00328 //HACK: render2d and render should probably be merged somehow, too much copy and paste here
00329 
00330 void zShapeCircle::render2d(tCoord scale) const {
00331 #ifndef DEDICATED
00332 
00333     // HACK
00334     int sg_segments = 8;
00335     // HACK
00336 
00337     //if ( color_.a_ > .7f )
00338     //    color_.a_ = .7f;
00339     if ( color_.a_ <= 0 )
00340         return;
00341 
00342     REAL currAngle = rotation2.evaluate(lasttime_);
00343     eCoord rot( cos(currAngle), sin(currAngle) );
00344 
00345     GLfloat m[4][4]={{rot.x,rot.y,0,0},
00346                      {-rot.y,rot.x,0,0},
00347                      {0,0,1,0},
00348                      {posx_.Evaluate(lasttime_ - referencetime_), posy_.Evaluate(lasttime_ - referencetime_), 0,1}};
00349 
00350     ModelMatrix();
00351     glPushMatrix();
00352 
00353     glMultMatrixf(&m[0][0]);
00354 
00355     BeginLines();
00356 
00357     const REAL seglen = M_PI / sg_segments;
00358 
00359     color_.Apply();
00360 
00361     REAL effectiveRadius;
00362     effectiveRadius = scale_.Evaluate(lasttime_ - referencetime_) * radius.Evaluate(lasttime_ - referencetime_);
00363     if (effectiveRadius >= 0.0)
00364     {
00365         for ( int i = sg_segments - 1; i>=0; --i )
00366         {
00367             REAL a = i * 2 * 3.14159 / REAL( sg_segments );
00368             REAL b = a + seglen;
00369 
00370             REAL sa = effectiveRadius * sin(a);
00371             REAL ca = effectiveRadius * cos(a);
00372             REAL sb = effectiveRadius * sin(b);
00373             REAL cb = effectiveRadius * cos(b);
00374 
00375             glVertex2f(sa, ca);
00376             glVertex2f(sb, cb);
00377         }
00378     }
00379     RenderEnd();
00380     glPopMatrix();
00381 #endif
00382 }
00383 
00384 //
00385 zShapePolygon::zShapePolygon(nMessage &m):zShape(m),
00386         points()
00387 {
00388     int numPoints;
00389     m >> numPoints;
00390 
00391     // read the polygon shape
00392     for( ; numPoints>0 && !m.End(); numPoints-- )
00393     {
00394         tFunction tfX, tfY;
00395         m >> tfX;
00396         m >> tfY;
00397 
00398         addPoint( myPoint( tfX, tfY ) );
00399     }
00400 }
00401 
00402 zShapePolygon::zShapePolygon(eGrid *grid, unsigned short idZone):
00403         zShape(grid, idZone),
00404         points()
00405 {}
00406 
00407 /*
00408  * to create a shape on the clients
00409  */
00410 void zShapePolygon::WriteCreate( nMessage & m )
00411 {
00412     zShape::WriteCreate(m);
00413 
00414     int numPoints;
00415     numPoints = points.size();
00416     m << numPoints;
00417 
00418     std::vector< myPoint >::const_iterator iter;
00419     for(iter = points.begin();
00420             iter != points.end();
00421             ++iter)
00422     {
00423         m << (*iter).first;
00424         m << (*iter).second;
00425     }
00426 
00427     //    WriteSync( m );
00428 }
00429 
00430 bool zShapePolygon::isInside(eCoord anECoord) {
00431     // The following is a modified version of code by Randolph Franklin,
00432     // Found at http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/
00433 
00434     // Hack!!!!
00435     // All the poinst need to be moved around the x,y position
00436     // then scaled
00437     //    REAL r = scale_->GetFloat();
00438     REAL x = anECoord.x;
00439     REAL y = anECoord.y;
00440     int c = 0;
00441 
00442     std::vector< myPoint >::const_iterator iter = points.end() - 1;
00443     // We need to position the prevIter to the last point.
00444     REAL currentScale = 0.0;
00445     REAL x_ = (*iter).first.Evaluate(lasttime_ - referencetime_);
00446     REAL y_ = (*iter).second.Evaluate(lasttime_ - referencetime_);
00447     tCoord centerPos = tCoord(posx_.Evaluate(lasttime_ - referencetime_), posy_.Evaluate(lasttime_ - referencetime_));
00448     //    tCoord rotation = tCoord( cosf(rotation_.Evaluate(lasttime_ - referencetime_)), sinf(rotation_.Evaluate(lasttime_ - referencetime_)) );
00449     tCoord rotation = tCoord( cosf(rotation2.evaluate(lasttime_)), sinf(rotation2.evaluate(lasttime_)) );
00450     currentScale = scale_.Evaluate(lasttime_ - referencetime_);
00451     tCoord previous = tCoord(x_, y_).Turn( rotation )*currentScale + centerPos;
00452 
00453     REAL xpp = previous.x;
00454     REAL ypp = previous.y;
00455 
00456     if(currentScale > 0.0)
00457     {
00458         for(iter = points.begin();
00459                 iter != points.end();
00460                 ++iter)
00461         {
00462             x_ = (*iter).first.Evaluate(lasttime_ - referencetime_);
00463             y_ = (*iter).second.Evaluate(lasttime_ - referencetime_);
00464             tCoord current = tCoord(x_, y_).Turn( rotation )*currentScale + centerPos;
00465 
00466             REAL xp = current.x;
00467             REAL yp = current.y;
00468 
00469             if ((((yp <= y) && (y < ypp)) || ((ypp <= y) && (y < yp))) &&
00470                     (x < (xpp - xp) * (y - yp) / (ypp - yp) + xp))
00471                 c = !c;
00472 
00473             xpp = xp; ypp = yp;
00474         }
00475     }
00476 
00477     return c;
00478 }
00479 #include "eNetGameObject.h"
00480 #include "ePlayer.h"
00481 bool zShapePolygon::isInteracting(eGameObject * target)
00482 {
00483     bool interact = false;
00484     gCycle* prey = dynamic_cast< gCycle* >( target );
00485     if ( prey )
00486     {
00487         if ( prey->Player() && prey->Alive() )
00488         {
00489             // Is the player inside or outside the zone
00490             if ( isInside( prey->Position() ) )
00491             {
00492                 interact = true;
00493             }
00494         }
00495     }
00496     return interact;
00497 }
00498 
00499 void zShapePolygon::render(const eCamera * cam )
00500 {
00501 #ifndef DEDICATED
00502 
00503     // HACK
00504     //  int sg_segments = 11;
00505     bool sr_alphaBlend = true;
00506     // HACK
00507 
00508     if ( color_.a_ > .7f )
00509         color_.a_ = .7f;
00510     if ( color_.a_ <= 0 )
00511         return;
00512 
00513 
00514     ModelMatrix();
00515     glPushMatrix();
00516 
00517     glDisable(GL_LIGHT0);
00518     glDisable(GL_LIGHT1);
00519     glDisable(GL_LIGHTING);
00520     glDisable(GL_CULL_FACE);
00521     glBlendFunc( GL_SRC_ALPHA, GL_ONE );
00522 
00523     //glDisable(GL_TEXTURE);
00524     glDisable(GL_TEXTURE_2D);
00525 
00526     //    glMultMatrixf(&m[0][0]);
00527 
00528     REAL currentScale = 0.0;
00529     glTranslatef(posx_.Evaluate(lasttime_ - referencetime_), posy_.Evaluate(lasttime_ - referencetime_), 0);
00530     currentScale = scale_.Evaluate(lasttime_ - referencetime_);
00531 
00532     if(currentScale > 0.0)
00533     {
00534         glScalef(currentScale, currentScale, 1.0);
00535 
00536         glRotatef(rotation2.evaluate(lasttime_)*180/M_PI, 0.0, 0.0, 1.0);
00537 
00538         if ( sr_alphaBlend ) {
00539             glDepthMask(GL_FALSE);
00540             BeginQuads();
00541         } else {
00542             RenderEnd();
00543             glDepthMask(GL_TRUE);
00544             BeginLineStrip();
00545         }
00546 
00547         //    const REAL seglen = .2f;
00548         const REAL bot = 0.0f;
00549         const REAL top = 5.0f; // + ( lastTime - createTime_ ) * .1f;
00550 
00551         color_.Apply();
00552 
00553 
00554 
00555 
00556         std::vector< myPoint >::const_iterator iter;
00557         std::vector< myPoint >::const_iterator prevIter = points.end() - 1;
00558 
00559         for(iter = points.begin();
00560                 iter != points.end();
00561                 prevIter = iter++)
00562         {
00563             REAL xp = (*iter).first.Evaluate( lasttime_ - referencetime_ ) ;
00564             REAL yp = (*iter).second.Evaluate( lasttime_ - referencetime_ ) ;
00565             REAL xpp = (*prevIter).first.Evaluate( lasttime_ - referencetime_ ) ;
00566             REAL ypp = (*prevIter).second.Evaluate( lasttime_ - referencetime_ ) ;
00567 
00568             glVertex3f(xp, yp, bot);
00569             glVertex3f(xp, yp, top);
00570             glVertex3f(xpp, ypp, top);
00571             glVertex3f(xpp, ypp, bot);
00572 
00573             if ( !sr_alphaBlend )
00574             {
00575                 glVertex3f(xp, yp, bot);
00576                 RenderEnd();
00577                 BeginLineStrip();
00578             }
00579         }
00580 
00581         RenderEnd();
00582 
00583         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00584         glDepthMask(GL_TRUE);
00585     }
00586     glPopMatrix();
00587 #endif
00588 }
00589 void zShapePolygon::render2d(tCoord scale) const {
00590 #ifndef DEDICATED
00591 
00592     //if ( color_.a_ > .7f )
00593     //    color_.a_ = .7f;
00594     if ( color_.a_ <= 0 )
00595         return;
00596 
00597 
00598     ModelMatrix();
00599     glPushMatrix();
00600 
00601     REAL currentScale = 0.0;
00602     glTranslatef(posx_.Evaluate(lasttime_ - referencetime_), posy_.Evaluate(lasttime_ - referencetime_), 0);
00603 
00604     currentScale = scale_.Evaluate(lasttime_ - referencetime_);
00605 
00606     if(currentScale > 0.0)
00607     {
00608         glScalef(currentScale, currentScale, 1.0);
00609 
00610         glRotatef(rotation2.evaluate(lasttime_)*180/M_PI, 0.0, 0.0, 1.0);
00611 
00612         BeginLines();
00613 
00614         //    const REAL seglen = .2f;
00615 
00616         color_.Apply();
00617 
00618         std::vector< myPoint >::const_iterator iter;
00619         std::vector< myPoint >::const_iterator prevIter = points.end() - 1;
00620 
00621         for(iter = points.begin();
00622                 iter != points.end();
00623                 prevIter = iter++)
00624         {
00625             REAL xp = (*iter).first.Evaluate( lasttime_ - referencetime_ ) ;
00626             REAL yp = (*iter).second.Evaluate( lasttime_ - referencetime_ ) ;
00627             REAL xpp = (*prevIter).first.Evaluate( lasttime_ - referencetime_ ) ;
00628             REAL ypp = (*prevIter).second.Evaluate( lasttime_ - referencetime_ ) ;
00629 
00630             glVertex2f(xp, yp);
00631             glVertex2f(xpp, ypp);
00632         }
00633 
00634         RenderEnd();
00635     }
00636     glPopMatrix();
00637 #endif
00638 }
00639 
00640 // the shapes's network initializator
00641 static nNOInitialisator<zShapeCircle> zoneCircle_init(350,"shapeCircle");
00642 static nNOInitialisator<zShapePolygon> zonePolygon_init(360,"shapePolygon");
00643 
00644 nDescriptor & zShapeCircle::CreatorDescriptor( void ) const
00645 {
00646     return zoneCircle_init;
00647 }
00648 
00649 nDescriptor & zShapePolygon::CreatorDescriptor( void ) const
00650 {
00651     return zonePolygon_init;
00652 }

Generated on Sat Mar 15 22:56:13 2008 for Armagetron Advanced by  doxygen 1.5.4