src/engine/eTess2.h

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00023   
00024 ***************************************************************************
00025 
00026 */
00027 
00028 #ifndef ArmageTron_TESS_H
00029 #define ArmageTron_TESS_H
00030 
00031 #include "tMemManager.h"
00032 #include "tList.h"
00033 #include "eCoord.h"
00034 #include "tHeap.h"
00035 #include <iostream>
00036 #include "eWall.h"
00037 
00038 extern int se_debugExt;
00039 
00040 class ePoint;
00041 //class eEdge;
00042 class eFace;
00043 class eWall;
00044 class eGameObject;
00045 class ePath;
00046 class eHalfEdge;
00047 class eGrid;
00048 
00049 // **********************************************************
00050 // * eDual: common base class for points and faces;
00051 // *         they are in a duality relation.
00052 // **********************************************************
00053 
00054 class eDual{
00055     friend class eHalfEdge;
00056     friend class eGrid;
00057     friend class eFace;
00058     friend class ePoint;
00059     //    friend class eGameObject;
00060 
00061 public:
00062     eDual();    // empty constructor
00063 
00064     eHalfEdge *Edge()const {return edge;}
00065 
00066     bool IsInGrid() const {return ID >= 0;}
00067 protected:
00068     ~eDual();  // destructor
00069 
00070     bool Check(int type);    // basic consistency check; type is 0 for points and 1 for faces.
00071     void Unlink(int type);   // removes itself from the edges' pointers. type is 0 for points and 1 for edges.
00072 
00073     int                             ID;           // list identification
00074     tJUST_CONTROLLED_PTR<eHalfEdge> edge;         // one of the edges that begin at this vertex/is a border of this edge
00075 };
00076 
00077 // information about from where the path came in pathfinding
00078 typedef enum { PATH_NEXT=0, PATH_PREV=1, PATH_OTHER_NEXT=2, PATH_PREV_OTHER=3,
00079                PATH_START=4, PATH_CLOSED=8, PATH_CLOSED_START=12, PATH_NONE=16}
00080 ePATH_ORIGIN;
00081 
00082 class eHalfEdge: public tHeapElement, public eWallHolder, public tReferencable< eHalfEdge > {
00083     friend class eDual;
00084     friend class ePoint;
00085     friend class eFace;
00086     friend class eGrid;
00087     friend class eTempEdge;
00088     friend class eWall;
00089     friend class tReferencable< eHalfEdge >;
00090 
00091     ~eHalfEdge();                  // destructor unlinking all pointers
00092     eHalfEdge(ePoint *p = NULL);            // empty constructor
00093 public:
00094     eHalfEdge(ePoint *a, ePoint *b,eWall *w=NULL);   // full line constructor
00095 
00096     // wall management
00097     //  eWall *Wall()const {return wall;}
00098     void SetWall(eWall *w);
00099     void ClearWall( void );
00100 
00101     void SetOther(eHalfEdge *e)
00102     {
00103         tASSERT(e != this);
00104 
00105         if (e == other)
00106             return;
00107 
00108         if (other)
00109             other->other = NULL;
00110 
00111         if (e->other)
00112             e->other->other = NULL;
00113 
00114         e->other = this;
00115         other = e;
00116     }
00117 
00118     // completely delete this edge and its other half
00119     void Destroy()
00120     {
00121         tJUST_CONTROLLED_PTR< eHalfEdge > holder( this );
00122         Unlink();
00123     }
00124 
00125     // assuming c is on this line: how far is it in direction of the endpoint?
00126     REAL Ratio(const eCoord &c) const;
00127 
00128     // the vector from beginning to end
00129     eCoord Vec() const;
00130 
00131     // are we allowed to replace it?
00132     bool Movable() const{return !GetWall() && (!other || !other->GetWall());}
00133 
00134     // splitting
00135     bool Splittable() const;
00136 
00137     // split eEdge at s;
00138     void Split(eHalfEdge *& e1,eHalfEdge *& e2,ePoint *s);
00139 
00140     // does the same, but guarantees that first lies in e1.
00141     //  void SplitOriented(eHalfEdge *& e1,eHalfEdge *& e2,ePoint *s,ePoint *first);
00142 
00143     // different split along an eEdge::
00144     // this:   XXXXXWWWWZZZZWWWWWWWWWW
00145     // e:      ...........
00146 
00147     // after:
00148     // e1:                ZZWWWWWWWWWW
00149     // e:      XXXXXWWWWZZ
00150     // void Split(eHalfEdge * e,eHalfEdge *& e1);
00151 
00152 
00153     // get the intersection point of two edges:
00154     // stupid intersection without checks; returned point
00155     // does not allways lie within the two edges
00156     eCoord IntersectWithCareless(const eHalfEdge *e2) const;
00157 
00158     // the same, but with checks: if the two edges don't intersect,
00159     // NULL is returned.
00160     ePoint * IntersectWith(const eHalfEdge *e2) const;
00161 
00162     // inserts an eEdge into the grid
00163     void CopyIntoGrid(eGrid *grid, bool change_grid=1);
00164 
00165     bool Simplify(eGrid *grid);
00166     // try to get rid of this eEdge; return value: can we delete it?
00167 
00168     // I/O:
00169     void Print(std::ostream &s) const;
00170 
00171     /*
00172     // mark this as edge of vision
00173     void MarkCheckVis(int i);
00174     static void MarkCheckVisAll(int i);
00175 
00176     // checks the visibility; return value: do we need to check
00177     // it again in the near future?
00178     bool UpdateVis(int i);
00179 
00180     // checks all edges on visibility for viewer i
00181     static void UpdateVisAll();
00182     static void UpdateVisAll(int viewer);
00183 
00184 
00185 
00186     eFace * NearerToViewer(int i);    // which of the neighbours is
00187     // closer to viewer i?
00188     //static void check_vis(REAL time); // checks visibility of all edges
00189 
00190     static void SeethroughHasChanged(); // some eWalls changed their 
00191     // blocking height; check that!
00192 
00193     */
00194     // member inquiry:
00195     ePoint*    Point() const;
00196     eFace*     Face () const;
00197     eHalfEdge* Other() const {return other;}
00198     eHalfEdge* Next() const  {return next;}
00199 
00200 
00201     // pathfinding interface: find a path for gameobject from origin to target.
00202     static void FindPath(const eCoord& originPoint, const eFace* originFace,
00203                          const eCoord& targetPoint, const eFace* targetFace,
00204                          const eGameObject* gameObject,
00205                          ePath& path);
00206 
00207     static void ClearPathData();
00208 
00209     eWall* CrossesNewWall(const eGrid *grid) const; // check whether this edge
00210     // crosses any of the brand-new walls on the grid
00211 protected:
00212 
00213     // pathfinding temporary data:
00214     ePATH_ORIGIN origin_; // the origin of the path
00215 
00216     REAL MinPathLength(){ return Val(); }   // the minimum length of a path through this edge
00217     void SetMinPathLength( REAL length, tHeapBase& heap, ePATH_ORIGIN origin );
00218 
00219     void PossiblePath( ePATH_ORIGIN origin, REAL minLength ); // tell the pathfinder that there might be a path of total length minLength through this HalfEdge, coming from the given origin type.
00220 
00221     virtual tHeapBase *Heap() const; // pathfinding heap
00222 
00223     void Unlink();          // remove us from all lists
00224     bool Check() const;     // consistency check
00225 
00226     // member manipulation
00227     void SetPoint(ePoint *p);
00228 
00229     void SetFace(eFace *p);
00230 
00231     //  eEdgeViewer *edgeViewers; // ancor for attached edgeViewers
00232 
00233     int                             ID;
00234     tJUST_CONTROLLED_PTR<ePoint>    point;     // pointer to the point this edge begins at
00235     tJUST_CONTROLLED_PTR<eFace>     face;     // pointer to the face this edge it is an edge of
00236     tJUST_CONTROLLED_PTR<eHalfEdge> next;        // the next HalfEdge around the face. Asserts: next->face == face, next->point == other->point.
00237     tJUST_CONTROLLED_PTR<eHalfEdge> prev;        // the previouns HalfEdge around the face. Assert: next->prev == this
00238     tJUST_CONTROLLED_PTR<eHalfEdge> other;       // the other half of this edge
00239 
00240     //  tCHECKED_PTR(eWall) wall;  // is it a eWall? what type?
00241 };
00242 
00243 
00244 
00245 class ePoint:public eDual, public eCoord, public tReferencable< ePoint >{
00246     friend class tReferencable< ePoint >;
00247 
00248 public:
00249     ePoint()                         {}
00250     ePoint(const eCoord &c):eCoord(c){}
00251 
00252 
00253     bool Check()  {return eDual::Check(0);}
00254 
00255     // calculations
00256     bool operator==(const ePoint &a) const{return eCoord::operator==(a);}
00257     bool operator!=(const ePoint &a) const{return !eCoord::operator==(a);}
00258     eCoord operator-(const ePoint &a) const{return eCoord(x-a.x,y-a.y);}
00259     eCoord operator+(const ePoint &a) const{return eCoord(x+a.x,y+a.y);}
00260     REAL   operator*(const ePoint &a) const{return -x*a.y+y*a.x;}
00261     const eCoord &operator=(const eCoord &a){x=a.x;y=a.y;return *this;}
00262 
00263     bool operator==(const eCoord &a) const{return eCoord::operator==(a);}
00264     bool operator!=(const eCoord &a) const{return !eCoord::operator==(a);}
00265     eCoord operator-(const eCoord &a) const{return eCoord(x-a.x,y-a.y);}
00266     eCoord operator-() const{return eCoord(-x,-y);}
00267     eCoord operator+(const eCoord &a) const{return eCoord(x+a.x,y+a.y);}
00268     REAL   operator*(const eCoord &a) const{return -x*a.y+y*a.x;}
00269     const eCoord &operator=(const ePoint &a){x=a.x;y=a.y;return *this;}
00270 
00271 
00272     // replaces all known pointers to *this with pointers to *P.
00273     void Replace(ePoint *P);
00274 
00275     void Unlink();
00276 
00277     void Print(std::ostream &s) const;
00278 protected:
00279     ~ePoint()     {Unlink();}
00280 };
00281 
00282 class eReplacementStorage;
00283 
00284 class eFace:public eDual, public tReferencable< eFace >{
00285     friend class tReferencable< eFace >;
00286 
00287     ~eFace();
00288 public:
00289     //  eFace(eGrid *Grid): grid(Grid)    {};
00290     eFace(eHalfEdge *a, eHalfEdge *b, eHalfEdge *c );
00291     eFace(eHalfEdge *a, eHalfEdge *b, eHalfEdge *c, tControlledPTR< eFace >& old );
00292     eFace(eHalfEdge *a, eHalfEdge *b, eHalfEdge *c, tControlledPTR< eFace >& old1, tControlledPTR< eFace >& old2 );
00293 
00294     // recreate the face surrounded by the three half edges
00295     void Create(eHalfEdge *a, eHalfEdge *b, eHalfEdge *c);
00296 
00297     //  eFace ()     {};
00298     //  eFace *F(int i){return e[i]->Other(this);}
00299 
00300     //  eCoord LeftVec(int i){return (*p[se_Left(i)])-(*p[i]);}
00301     // eCoord RightVec(int i){return (*p[se_Right(i)])-(*p[i]);}
00302 
00303 
00304     bool Check()  {return eDual::Check(1);}
00305 
00306     //  int FindPoint(const ePoint *P) const; // returns -1, if P is not a point
00307     // of this eFace, else the p[FindPoint(P)]=P.
00308     // int FindEdge(const eHalfEdge *E) const; // same
00309 
00310     void Print(std::ostream &s) const;
00311 
00312     void Unlink();
00313 
00314     // ckeck if the given point lies inside this face (edges included)
00315     bool IsInside( const eCoord& coord ) const;
00316 
00317     // ckeck if the given point lies inside this face; return value positive if it is inside and negative if outside
00318     REAL Insideness( const eCoord& coord, const eCoord& direction, const eCoord& lastDirection ) const;
00319     REAL Insideness( const eCoord& coord, const eCoord& direction ) const;
00320     REAL Insideness( const eCoord& coord ) const;
00321 
00322     // find a replacement for this face that contains the given coordinates for an object moving in the given directions
00323     eFace* FindReplacement( const eCoord& coord, const eCoord& direction, const eCoord& lastDirection ) const;
00324     eFace* FindReplacement( const eCoord& coord, const eCoord& direction ) const;
00325     eFace* FindReplacement( const eCoord& coord ) const;
00326 
00327     // check the area of this face; if it is negative, modify it to fix it and return true.
00328     bool CorrectArea();
00329 
00330     /*
00331     // visibility by viewer i
00332     void SetVisHeight(int i,REAL h);
00333     static void SetVisHeightAll(int i,REAL h);
00334 
00335 
00336     static void UpdateVisAll(int num=1);    // removes faces from the vis list
00337     void UpdateVis(int i);      // removes this eFace from the vis list
00338     */
00339     eFace* nextProcessed;
00340 
00341     // returns the array of stored replacements
00342     eReplacementStorage& GetReplacementStorage() const;
00343 protected:
00344     /*
00345     REAL   visHeight[MAX_VIEWERS]; // at which height can the
00346     // cameras see into this eFace?
00347     static int s_currentCheckVis[MAX_VIEWERS];
00348     */
00349 
00350     //  eGrid *grid;
00351 private:
00352     mutable eReplacementStorage* replacementStorage;
00353 };
00354 
00355 
00356 
00357 
00358 
00359 /*
00360 // a base class for the next two classes: connects an eEdge and a viewer
00361 class eEdgeViewer{
00362 
00363   friend class eEdge;
00364  protected:
00365   //  tCHECKED_PTR(eEdgeViewer) next;
00366   eEdgeViewer *next;
00367 
00368   tJUST_CONTROLLED_PTR(eHalfEdge) e;      // the eEdge we belong to
00369   int viewer;                             // and the viewer
00370      
00371   eEdgeViewer **Ref();
00372 
00373 public:
00374   eEdgeViewer(eHalfEdge *E,int v);
00375 
00376   virtual ~eEdgeViewer();
00377   
00378   virtual void Render();
00379 };
00380 
00381 // tEvents for a viewer crossing an eEdge (that is, the straight
00382 // prolongiation of the eEdge):
00383 
00384 class eViewerCrossesEdge: public tEvent,public eEdgeViewer{
00385 protected:
00386   virtual tHeapBase *Heap();
00387 public:
00388   eViewerCrossesEdge(eHalfEdge *E,int v);
00389   virtual ~eViewerCrossesEdge();
00390   
00391   virtual bool Check(REAL dist);
00392 
00393   virtual void Render();
00394 };
00395 
00396 */
00397 
00398 
00399 
00400 // inline implementations:
00401 
00402 
00403 
00404 
00405 
00406 inline eDual::eDual():ID(-1),edge(NULL){}
00407 
00408 
00409 inline eCoord eHalfEdge::Vec() const{
00410     tASSERT(other);
00411     return *(other->Point()) - *Point();
00412 }
00413 
00414 // member manipulation
00415 inline ePoint *eHalfEdge::Point() const { return point;}
00416 inline void eHalfEdge::SetPoint(ePoint *p) {point = p;}
00417 
00418 inline eFace *eHalfEdge::Face() const {return face;}
00419 inline void eHalfEdge::SetFace(eFace *f) {face = f;}
00420 
00421 
00422 inline REAL eHalfEdge::Ratio(const eCoord &c)const
00423 {
00424     return eCoord::V(*Point(),c,*other->Point());
00425 }
00426 
00427 
00428 
00429 
00430 inline std::ostream & operator<<(std::ostream &s,const ePoint &x){x.Print(s);return s;}
00431 inline std::ostream & operator<<(std::ostream &s,const eHalfEdge &x){x.Print(s);return s;}
00432 inline std::ostream & operator<<(std::ostream &s,const eFace &x){x.Print(s);return s;}
00433 
00434 
00435 
00436 
00437 #endif
00438 
00439 
00440 
00441 

Generated on Sat Mar 15 22:55:47 2008 for Armagetron Advanced by  doxygen 1.5.4