Added aqua_speed for rite geo 50 tryker
[ryzomcore.git] / nel / tools / pacs / build_rbank / surface_splitter.h
blob3cf035e9d3263f7407b2ecc3287c0a9a6b32d994
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #ifndef NL_SURFACE_SPLITTER_H
18 #define NL_SURFACE_SPLITTER_H
20 #include "nel/misc/types_nl.h"
22 #include "nel/pacs/local_retriever.h"
23 #include "nel/pacs/quad_grid.h"
25 #include <map>
27 /**
28 * TODO Class description
29 * \author Benjamin Legros
30 * \author Nevrax France
31 * \date 2002
33 class CSurfaceSplitter
35 public:
37 ///
38 class CVector2s64;
39 class CSurfaceId;
40 class CChain;
41 class CLoop;
42 class CSurface;
44 ///
45 class CFixed64
47 protected:
48 sint64 _Value;
49 public:
50 CFixed64() : _Value(0) {}
51 CFixed64(const sint64 &v) : _Value(v) {}
52 CFixed64(const double &v) : _Value((sint64)(v*4294967296.0)) {}
53 CFixed64(const CFixed64 &v) : _Value(v._Value) {}
55 operator double(void) const { return ((double)_Value) / 4294967296.0; }
56 operator float(void) const { return ((float)_Value) / 4294967296.0f; }
57 operator sint64(void) const { return _Value; }
59 CFixed64 operator + (const CFixed64 &f) const { return CFixed64(_Value + f._Value); }
60 CFixed64 operator - (const CFixed64 &f) const { return CFixed64(_Value - f._Value); }
61 CFixed64 operator - () const { return CFixed64(-_Value); }
62 CFixed64 operator * (const CFixed64 &f) const
64 sint64 vh = _Value>>32;
65 sint64 vl = _Value&0xffffffff;
66 sint64 uh = f._Value>>32;
67 sint64 ul = f._Value&0xffffffff;
69 sint64 res = ((vh*uh)<<32)+(vh*ul+uh*vl)+((uint64)(vl*ul)>>32);
70 double fres = ((double)res) / 4294967296.0;
71 double cfres = (double)(*this) * (double)f;
72 return CFixed64(res);
74 CFixed64 operator / (const CFixed64 &f) const
76 if (f._Value == 0)
77 return CFixed64();
79 sint sign = 0;
80 uint64 a = _Value;
81 uint64 b = f._Value;
83 if ((sint64)a < 0)
84 a = -(sint64)a, sign ^= 1;
85 if ((sint64)b < 0)
86 b = -(sint64)b, sign ^= 1;
88 uint64 lb = INT64_CONSTANT (0x8000000000000000);
89 uint64 q = 0;
90 uint64 nh = a>>32;
91 uint64 nl = a<<32;
93 while (lb != 0)
95 if (nh >= b)
97 q |= (lb+lb);
98 nh -= b;
100 nh = (nh+nh) + (nl&lb ? 1 : 0);
101 lb >>= 1;
104 // round final bit
105 if (nh >= b)
106 ++q;
108 CFixed64 result(sign ? -(sint64)q : +(sint64)q );
109 return result;
112 CFixed64 &operator += (const CFixed64 &f) { _Value+=f._Value; return *this; }
113 CFixed64 &operator -= (const CFixed64 &f) { _Value-=f._Value; return *this; }
114 CFixed64 &operator *= (const CFixed64 &f) { *this = *this*f; return *this; }
115 CFixed64 &operator /= (const CFixed64 &f) { *this = *this/f; return *this; }
117 bool operator == (const CFixed64 &f) const { return _Value == f._Value; }
118 bool operator != (const CFixed64 &f) const { return _Value != f._Value; }
119 bool operator < (const CFixed64 &f) const { return _Value < f._Value; }
120 bool operator <= (const CFixed64 &f) const { return _Value <= f._Value; }
121 bool operator >= (const CFixed64 &f) const { return _Value >= f._Value; }
122 bool operator > (const CFixed64 &f) const { return _Value > f._Value; }
124 double sqnorm() const { return (double)(*this * *this); }
125 double norm() const { return sqrt(sqnorm()); }
129 class CVector2s64
131 public:
132 CFixed64 x;
133 CFixed64 y;
135 CVector2s64() : x(), y() {}
136 CVector2s64(const sint64 &X, const sint64 &Y) : x(X), y(Y) {}
137 CVector2s64(const CFixed64 &X, const CFixed64 &Y) : x(X), y(Y) {}
138 CVector2s64(const NLMISC::CVector &v) : x(v.x), y(v.y) {}
139 CVector2s64(const NLMISC::CVectorD &v) : x(v.x), y(v.y) {}
140 CVector2s64(const NLPACS::CVector2s &v) : x(((sint64)v.x) << 25), y(((sint64)v.y) << 25) {}
142 CVector2s64 operator + (const CVector2s64 &v) const { return CVector2s64(x+v.x, y+v.y); }
143 CVector2s64 operator - (const CVector2s64 &v) const { return CVector2s64(x-v.x, y-v.y); }
144 CVector2s64 operator * (sint64 s) const { return CVector2s64(x*CFixed64(s), y*CFixed64(s)); }
145 CVector2s64 operator * (CFixed64 s) const { return CVector2s64(x*s, y*s); }
146 CVector2s64 operator * (double s) const { return CVector2s64(x*CFixed64(s), y*CFixed64(s)); }
147 CVector2s64 operator / (sint64 s) const { return CVector2s64(x*CFixed64(s), y*CFixed64(s)); }
148 CVector2s64 operator / (CFixed64 s) const { return CVector2s64(x*s, y*s); }
149 CVector2s64 operator / (double s) const { return CVector2s64(x*CFixed64(s), y*CFixed64(s)); }
150 CFixed64 operator * (const CVector2s64 &v) const { return x*v.x + y*v.y; }
151 CFixed64 operator ^ (const CVector2s64 &v) const { return x*v.y - y*v.x; }
153 bool operator == (const CVector2s64 &v) const { return x == v.x && y == v.y; }
154 bool operator != (const CVector2s64 &v) const { return x != v.x || y != v.y; }
156 CVector2s64 &operator += (const CVector2s64 &v)
158 x += v.x;
159 y += v.y;
160 return *this;
162 CVector2s64 &operator -= (const CVector2s64 &v)
164 x -= v.x;
165 y -= v.y;
166 return *this;
168 CVector2s64 &operator *= (sint64 s)
170 CFixed64 ss(s);
171 x *= ss;
172 y *= ss;
173 return *this;
175 CVector2s64 &operator *= (double s)
177 CFixed64 ss(s);
178 x *= ss;
179 y *= ss;
180 return *this;
183 NLMISC::CVector asVector() const
185 return NLMISC::CVector((float)x, (float)y, 0.0f);
187 NLMISC::CVectorD asVectorD() const
189 return NLMISC::CVectorD((double)x, (double)y, 0.0);
194 class CSurfaceId
196 public:
197 uint16 Instance;
198 uint16 Surface;
199 uint16 SubSurface;
201 CSurfaceId(uint16 instance=65535, uint16 surface=65535, uint16 subsurface=0) :
202 Instance(instance),
203 Surface(surface),
204 SubSurface(subsurface) {}
206 bool operator == (const CSurfaceId &id) const { return Instance == id.Instance && Surface == id.Surface && SubSurface == id.SubSurface; }
207 bool operator != (const CSurfaceId &id) const { return !(*this == id); }
209 bool operator < (const CSurfaceId &id) const
211 if (Instance < id.Instance)
212 return true;
213 else if (Instance > id.Instance)
214 return false;
215 else if (Surface < id.Surface)
216 return true;
217 else if (Surface > id.Surface)
218 return false;
219 else
220 return SubSurface < id.SubSurface;
223 bool operator > (const CSurfaceId &id) const { return id < *this; }
224 bool operator <= (const CSurfaceId &id) const { return *this == id || *this < id; }
225 bool operator >= (const CSurfaceId &id) const { return *this == id || id < *this; }
229 class CChainId
231 public:
232 CChainId(uint32 id=0) : Id(id) {}
233 uint32 Id;
235 bool operator == (const CChainId &id) const { return Id == id.Id; }
236 bool operator != (const CChainId &id) const { return !(*this == id); }
237 bool operator < (const CChainId &id) const { return Id < id.Id; }
238 bool operator > (const CChainId &id) const { return id < *this; }
239 bool operator <= (const CChainId &id) const { return *this == id || *this < id; }
240 bool operator >= (const CChainId &id) const { return *this == id || id < *this; }
245 class CEdgeId
247 public:
248 CEdgeId(const CChainId &chain=CChainId(), uint edge=0) : Chain(chain), Edge(edge) {}
249 CChainId Chain;
250 uint Edge;
253 typedef NLPACS::CQuadGrid<CEdgeId> TEdgeGrid;
257 class CTipId
259 public:
260 CTipId(uint32 id=0) : Id(id) {}
261 uint32 Id;
263 bool operator == (const CTipId &id) const { return Id == id.Id; }
264 bool operator != (const CTipId &id) const { return !(*this == id); }
265 bool operator < (const CTipId &id) const { return Id < id.Id; }
266 bool operator > (const CTipId &id) const { return id < *this; }
267 bool operator <= (const CTipId &id) const { return *this == id || *this < id; }
268 bool operator >= (const CTipId &id) const { return *this == id || id < *this; }
275 class CChain
277 public:
278 CChainId Id;
279 CSurfaceId Left;
280 CSurfaceId Right;
281 CTipId Start;
282 CTipId Stop;
283 std::vector<CVector2s64> Vertices;
284 std::vector<TEdgeGrid::CIterator> Iterators;
285 bool DontSplit;
288 CChain() : DontSplit(false) {}
291 void dump(bool forward) const
293 NLMISC::InfoLog->displayRawNL("Chain:%d[Left=%d:%d:%d,Right=%d:%d:%d]", Id.Id, Left.Instance, Left.Surface, Left.SubSurface, Right.Instance, Right.Surface, Right.SubSurface);
294 sint i, j=0;
295 if (forward)
297 for (i=0; i<(sint)Vertices.size(); ++i, ++j)
298 NLMISC::InfoLog->displayRawNL("%d;%.3f;%.3f", j, (double)Vertices[i].x, (double)Vertices[i].y);
300 else
302 for (i=(sint)Vertices.size()-1; i>=0; --i, ++j)
303 NLMISC::InfoLog->displayRawNL("%d;%.3f;%.3f", j, (double)Vertices[i].x, (double)Vertices[i].y);
311 class CTip
313 public:
314 CTipId Id;
315 CVector2s64 Tip;
316 std::vector<CChainId> Chains;
322 class CLoop
324 public:
325 CSurfaceId Surface;
326 std::vector<CChainId> Chains;
329 void dump(const CSurfaceSplitter &splitter) const
331 uint i;
332 for (i=0; i<Chains.size(); ++i)
334 const CChain *chain = splitter.getChain(Chains[i]);
335 if (chain != NULL)
336 chain->dump(Surface == chain->Left);
341 void removeChain(CChainId chain)
343 std::vector<CChainId>::iterator it;
344 for (it=Chains.begin(); it!=Chains.end(); )
346 if (*it == chain)
347 it = Chains.erase(it);
348 else
349 ++it;
354 class iterator
356 public:
357 CSurfaceSplitter *pSplitter;
358 CLoop *pLoop;
359 sint Chain;
360 CChain *pChain;
361 sint ChainVertex;
362 sint8 Direction;
363 sint8 ChainDirection;
365 iterator(CSurfaceSplitter *splitter=NULL, CLoop *loop=NULL, bool forward=true) : pSplitter(splitter), pLoop(loop), Chain(0), pChain(NULL), ChainVertex(0), Direction(0), ChainDirection(0)
367 Direction = forward ? +1 : -1;
368 if (splitter == NULL || pLoop == NULL)
369 return;
370 Chain = (Direction>0 ? 0 : (sint)pLoop->Chains.size()-1);
371 resetChain();
373 iterator(const iterator &it)
375 *this = it;
378 iterator &operator = (const iterator &it)
380 pSplitter = it.pSplitter;
381 pLoop = it.pLoop;
382 Chain = it.Chain;
383 pChain = it.pChain;
384 ChainVertex = it.ChainVertex;
385 Direction = it.Direction;
386 return *this;
388 bool operator == (const iterator &it)
390 return pSplitter == it.pSplitter &&
391 pLoop == it.pLoop &&
392 Chain == it.Chain &&
393 ChainVertex == it.ChainVertex;
395 bool operator != (const iterator &it) { return !(*this == it); }
397 // ++it
398 iterator &operator ++ ()
400 ChainVertex += ChainDirection;
401 if (ChainVertex == 0 || ChainVertex == (sint)pChain->Vertices.size()-1)
403 Chain += Direction;
404 resetChain();
407 return *this;
410 // it++
411 iterator operator ++ (int)
413 iterator tmp(*this);
415 ChainVertex += ChainDirection;
416 if (ChainVertex == 0 || ChainVertex == (sint)pChain->Vertices.size()-1)
418 Chain += Direction;
419 resetChain();
422 return tmp;
425 void resetChain()
427 if (Chain < 0 || Chain == (sint)pLoop->Chains.size())
429 pSplitter = NULL;
430 pLoop = NULL;
431 Chain = 0;
432 pChain = NULL;
433 ChainVertex = 0;
434 Direction = 0;
435 ChainDirection = 0;
436 return;
438 pChain = pSplitter->getChain(pLoop->Chains[Chain]);
439 ChainDirection = (pChain->Left == pLoop->Surface ? Direction : -Direction);
440 ChainVertex = (ChainDirection>0 ? 0 : (sint)pChain->Vertices.size()-1);
443 CVector2s64 operator * () const
445 return pChain->Vertices[ChainVertex];
453 class CSurface
455 public:
456 CSurfaceId Id;
457 std::vector<CLoop> Loops;
460 void dump(const CSurfaceSplitter &splitter) const
462 NLMISC::InfoLog->displayRawNL("---Surface:%d:%d:%d", Id.Instance, Id.Surface, Id.SubSurface);
463 uint i;
464 for (i=0; i<Loops.size(); ++i)
466 NLMISC::InfoLog->displayRawNL("Loop:%d", i);
467 Loops[i].dump(splitter);
472 void removeChain(CChainId chain)
474 uint i;
475 for (i=0; i<Loops.size(); ++i)
476 Loops[i].removeChain(chain);
480 protected:
481 typedef std::map<CSurfaceId, CSurface> TSurfaceMap;
482 typedef std::map<CChainId, CChain> TChainMap;
483 typedef std::map<CTipId, CTip> TTipMap;
485 TSurfaceMap _Surfaces;
486 uint _NumSurfaces;
487 TChainMap _Chains;
488 uint _NumChains;
489 TTipMap _Tips;
490 uint _NumTips;
492 TEdgeGrid _Edges;
495 public:
497 /// Constructor
498 CSurfaceSplitter();
501 void build(NLPACS::CLocalRetriever &lr);
504 CSurface *getSurface(const CSurfaceId &id)
506 TSurfaceMap::iterator it = _Surfaces.find(id);
507 return (it == _Surfaces.end() ? NULL : &((*it).second));
511 CChain *getChain(const CChainId &id)
513 TChainMap::iterator it = _Chains.find(id);
514 return (it == _Chains.end() ? NULL : &((*it).second));
518 const CSurface *getSurface(const CSurfaceId &id) const
520 TSurfaceMap::const_iterator it = _Surfaces.find(id);
521 return (it == _Surfaces.end() ? NULL : &((*it).second));
525 const CChain *getChain(const CChainId &id) const
527 TChainMap::const_iterator it = _Chains.find(id);
528 return (it == _Chains.end() ? NULL : &((*it).second));
533 protected:
536 void buildChain(NLPACS::CLocalRetriever &lr, uint chain);
539 void buildSurface(NLPACS::CLocalRetriever &lr, uint surface);
544 void initEdgeGrid();
549 void splitChains();
552 void splitChain(TChainMap::iterator it, uint &numInters);
557 void dump() const
559 TSurfaceMap::const_iterator it;
561 for (it=_Surfaces.begin(); it!=_Surfaces.end(); ++it)
562 (*it).second.dump(*this);
566 void dumpChain(CChainId chain) const
568 TChainMap::const_iterator it = _Chains.find(chain);
569 if (it == _Chains.end())
570 return;
572 (*it).second.dump(true);
578 bool intersect(const CVector2s64 &v0, const CVector2s64 &v1,
579 const CVector2s64 &c0, const CVector2s64 &c1,
580 CVector2s64 &intersect, CFixed64 &ndist);
586 CChainId addChain(const CSurfaceId &left, const CSurfaceId &right, const std::vector<CVector2s64> &points, bool dontSplit=false);
589 void removeChain(CChainId chain);
592 void replaceChain(CChainId chain, const std::vector<CChainId> &chains);
596 #endif // NL_SURFACE_SPLITTER_H
598 /* End of surface_splitter.h */