3
*************************************************************************
5
ArmageTron -- Just another Tron Lightcycle Game in 3D.
6
Copyright (C) 2000 Manuel Moos (manuel@moosnet.de)
8
**************************************************************************
10
This program is free software; you can redistribute it and/or
11
modify it under the terms of the GNU General Public License
12
as published by the Free Software Foundation; either version 2
13
of the License, or (at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
***************************************************************************
28
#ifndef ArmageTron_TESS_H
29
#define ArmageTron_TESS_H
31
#include "tMemManager.h"
38
extern int se_debugExt;
49
// **********************************************************
50
// * eDual: common base class for points and faces;
51
// * they are in a duality relation.
52
// **********************************************************
55
friend class eHalfEdge;
59
// friend class eGameObject;
62
eDual(); // empty constructor
64
eHalfEdge *Edge()const {return edge;}
66
bool IsInGrid() const {return ID >= 0;}
68
~eDual(); // destructor
70
bool Check(int type); // basic consistency check; type is 0 for points and 1 for faces.
71
void Unlink(int type); // removes itself from the edges' pointers. type is 0 for points and 1 for edges.
73
int ID; // list identification
74
tJUST_CONTROLLED_PTR<eHalfEdge> edge; // one of the edges that begin at this vertex/is a border of this edge
77
// information about from where the path came in pathfinding
78
typedef enum { PATH_NEXT=0, PATH_PREV=1, PATH_OTHER_NEXT=2, PATH_PREV_OTHER=3,
79
PATH_START=4, PATH_CLOSED=8, PATH_CLOSED_START=12, PATH_NONE=16}
82
class eHalfEdge: public tHeapElement, public eWallHolder, public tReferencable< eHalfEdge > {
87
friend class eTempEdge;
89
friend class tReferencable< eHalfEdge >;
91
~eHalfEdge(); // destructor unlinking all pointers
92
eHalfEdge(ePoint *p = NULL); // empty constructor
94
eHalfEdge(ePoint *a, ePoint *b,eWall *w=NULL); // full line constructor
97
// eWall *Wall()const {return wall;}
98
void SetWall(eWall *w);
99
void ClearWall( void );
101
void SetOther(eHalfEdge *e)
112
e->other->other = NULL;
118
// completely delete this edge and its other half
121
tJUST_CONTROLLED_PTR< eHalfEdge > holder( this );
125
// assuming c is on this line: how far is it in direction of the endpoint?
126
REAL Ratio(const eCoord &c) const;
128
// the vector from beginning to end
131
// are we allowed to replace it?
132
bool Movable() const{return !GetWall() && (!other || !other->GetWall());}
135
bool Splittable() const;
138
void Split(eHalfEdge *& e1,eHalfEdge *& e2,ePoint *s);
140
// does the same, but guarantees that first lies in e1.
141
// void SplitOriented(eHalfEdge *& e1,eHalfEdge *& e2,ePoint *s,ePoint *first);
143
// different split along an eEdge::
144
// this: XXXXXWWWWZZZZWWWWWWWWWW
150
// void Split(eHalfEdge * e,eHalfEdge *& e1);
153
// get the intersection point of two edges:
154
// stupid intersection without checks; returned point
155
// does not allways lie within the two edges
156
eCoord IntersectWithCareless(const eHalfEdge *e2) const;
158
// the same, but with checks: if the two edges don't intersect,
160
ePoint * IntersectWith(const eHalfEdge *e2) const;
162
// inserts an eEdge into the grid
163
void CopyIntoGrid(eGrid *grid, bool change_grid=1);
165
bool Simplify(eGrid *grid);
166
// try to get rid of this eEdge; return value: can we delete it?
169
void Print(std::ostream &s) const;
172
// mark this as edge of vision
173
void MarkCheckVis(int i);
174
static void MarkCheckVisAll(int i);
176
// checks the visibility; return value: do we need to check
177
// it again in the near future?
178
bool UpdateVis(int i);
180
// checks all edges on visibility for viewer i
181
static void UpdateVisAll();
182
static void UpdateVisAll(int viewer);
186
eFace * NearerToViewer(int i); // which of the neighbours is
187
// closer to viewer i?
188
//static void check_vis(REAL time); // checks visibility of all edges
190
static void SeethroughHasChanged(); // some eWalls changed their
191
// blocking height; check that!
195
ePoint* Point() const;
196
eFace* Face () const;
197
eHalfEdge* Other() const {return other;}
198
eHalfEdge* Next() const {return next;}
201
// pathfinding interface: find a path for gameobject from origin to target.
202
static void FindPath(const eCoord& originPoint, const eFace* originFace,
203
const eCoord& targetPoint, const eFace* targetFace,
204
const eGameObject* gameObject,
207
static void ClearPathData();
209
eWall* CrossesNewWall(const eGrid *grid) const; // check whether this edge
210
// crosses any of the brand-new walls on the grid
213
// pathfinding temporary data:
214
ePATH_ORIGIN origin_; // the origin of the path
216
REAL MinPathLength(){ return Val(); } // the minimum length of a path through this edge
217
void SetMinPathLength( REAL length, tHeapBase& heap, ePATH_ORIGIN origin );
219
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.
221
virtual tHeapBase *Heap() const; // pathfinding heap
223
void Unlink(); // remove us from all lists
224
bool Check() const; // consistency check
226
// member manipulation
227
void SetPoint(ePoint *p);
229
void SetFace(eFace *p);
231
// eEdgeViewer *edgeViewers; // ancor for attached edgeViewers
234
tJUST_CONTROLLED_PTR<ePoint> point; // pointer to the point this edge begins at
235
tJUST_CONTROLLED_PTR<eFace> face; // pointer to the face this edge it is an edge of
236
tJUST_CONTROLLED_PTR<eHalfEdge> next; // the next HalfEdge around the face. Asserts: next->face == face, next->point == other->point.
237
tJUST_CONTROLLED_PTR<eHalfEdge> prev; // the previouns HalfEdge around the face. Assert: next->prev == this
238
tJUST_CONTROLLED_PTR<eHalfEdge> other; // the other half of this edge
240
// tCHECKED_PTR(eWall) wall; // is it a eWall? what type?
245
class ePoint:public eDual, public eCoord, public tReferencable< ePoint >{
246
friend class tReferencable< ePoint >;
250
ePoint(const eCoord &c):eCoord(c){}
253
bool Check() {return eDual::Check(0);}
256
bool operator==(const ePoint &a) const{return eCoord::operator==(a);}
257
bool operator!=(const ePoint &a) const{return !eCoord::operator==(a);}
258
eCoord operator-(const ePoint &a) const{return eCoord(x-a.x,y-a.y);}
259
eCoord operator+(const ePoint &a) const{return eCoord(x+a.x,y+a.y);}
260
REAL operator*(const ePoint &a) const{return -x*a.y+y*a.x;}
261
const eCoord &operator=(const eCoord &a){x=a.x;y=a.y;return *this;}
263
bool operator==(const eCoord &a) const{return eCoord::operator==(a);}
264
bool operator!=(const eCoord &a) const{return !eCoord::operator==(a);}
265
eCoord operator-(const eCoord &a) const{return eCoord(x-a.x,y-a.y);}
266
eCoord operator-() const{return eCoord(-x,-y);}
267
eCoord operator+(const eCoord &a) const{return eCoord(x+a.x,y+a.y);}
268
REAL operator*(const eCoord &a) const{return -x*a.y+y*a.x;}
269
const eCoord &operator=(const ePoint &a){x=a.x;y=a.y;return *this;}
272
// replaces all known pointers to *this with pointers to *P.
273
void Replace(ePoint *P);
277
void Print(std::ostream &s) const;
279
~ePoint() {Unlink();}
282
class eReplacementStorage;
284
class eFace:public eDual, public tReferencable< eFace >{
285
friend class tReferencable< eFace >;
289
// eFace(eGrid *Grid): grid(Grid) {};
290
eFace(eHalfEdge *a, eHalfEdge *b, eHalfEdge *c );
291
eFace(eHalfEdge *a, eHalfEdge *b, eHalfEdge *c, tControlledPTR< eFace >& old );
292
eFace(eHalfEdge *a, eHalfEdge *b, eHalfEdge *c, tControlledPTR< eFace >& old1, tControlledPTR< eFace >& old2 );
294
// recreate the face surrounded by the three half edges
295
void Create(eHalfEdge *a, eHalfEdge *b, eHalfEdge *c);
298
// eFace *F(int i){return e[i]->Other(this);}
300
// eCoord LeftVec(int i){return (*p[se_Left(i)])-(*p[i]);}
301
// eCoord RightVec(int i){return (*p[se_Right(i)])-(*p[i]);}
304
bool Check() {return eDual::Check(1);}
306
// int FindPoint(const ePoint *P) const; // returns -1, if P is not a point
307
// of this eFace, else the p[FindPoint(P)]=P.
308
// int FindEdge(const eHalfEdge *E) const; // same
310
void Print(std::ostream &s) const;
314
// ckeck if the given point lies inside this face (edges included)
315
bool IsInside( const eCoord& coord ) const;
317
// ckeck if the given point lies inside this face; return value positive if it is inside and negative if outside
318
REAL Insideness( const eCoord& coord, const eCoord& direction, const eCoord& lastDirection ) const;
319
REAL Insideness( const eCoord& coord, const eCoord& direction ) const;
320
REAL Insideness( const eCoord& coord ) const;
322
// find a replacement for this face that contains the given coordinates for an object moving in the given directions
323
eFace* FindReplacement( const eCoord& coord, const eCoord& direction, const eCoord& lastDirection ) const;
324
eFace* FindReplacement( const eCoord& coord, const eCoord& direction ) const;
325
eFace* FindReplacement( const eCoord& coord ) const;
327
// check the area of this face; if it is negative, modify it to fix it and return true.
331
// visibility by viewer i
332
void SetVisHeight(int i,REAL h);
333
static void SetVisHeightAll(int i,REAL h);
336
static void UpdateVisAll(int num=1); // removes faces from the vis list
337
void UpdateVis(int i); // removes this eFace from the vis list
339
eFace* nextProcessed;
341
// returns the array of stored replacements
342
eReplacementStorage& GetReplacementStorage() const;
345
REAL visHeight[MAX_VIEWERS]; // at which height can the
346
// cameras see into this eFace?
347
static int s_currentCheckVis[MAX_VIEWERS];
352
mutable eReplacementStorage* replacementStorage;
360
// a base class for the next two classes: connects an eEdge and a viewer
365
// tCHECKED_PTR(eEdgeViewer) next;
368
tJUST_CONTROLLED_PTR(eHalfEdge) e; // the eEdge we belong to
369
int viewer; // and the viewer
374
eEdgeViewer(eHalfEdge *E,int v);
376
virtual ~eEdgeViewer();
378
virtual void Render();
381
// tEvents for a viewer crossing an eEdge (that is, the straight
382
// prolongiation of the eEdge):
384
class eViewerCrossesEdge: public tEvent,public eEdgeViewer{
386
virtual tHeapBase *Heap();
388
eViewerCrossesEdge(eHalfEdge *E,int v);
389
virtual ~eViewerCrossesEdge();
391
virtual bool Check(REAL dist);
393
virtual void Render();
400
// inline implementations:
406
inline eDual::eDual():ID(-1),edge(NULL){}
409
inline eCoord eHalfEdge::Vec() const{
411
return *(other->Point()) - *Point();
414
// member manipulation
415
inline ePoint *eHalfEdge::Point() const { return point;}
416
inline void eHalfEdge::SetPoint(ePoint *p) {point = p;}
418
inline eFace *eHalfEdge::Face() const {return face;}
419
inline void eHalfEdge::SetFace(eFace *f) {face = f;}
422
inline REAL eHalfEdge::Ratio(const eCoord &c)const
424
return eCoord::V(*Point(),c,*other->Point());
430
inline std::ostream & operator<<(std::ostream &s,const ePoint &x){x.Print(s);return s;}
431
inline std::ostream & operator<<(std::ostream &s,const eHalfEdge &x){x.Print(s);return s;}
432
inline std::ostream & operator<<(std::ostream &s,const eFace &x){x.Print(s);return s;}