From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/chain__quad_8cpp-source.html | 616 ++++++++++++++++++++++++++ 1 file changed, 616 insertions(+) create mode 100644 docs/doxygen/nel/chain__quad_8cpp-source.html (limited to 'docs/doxygen/nel/chain__quad_8cpp-source.html') diff --git a/docs/doxygen/nel/chain__quad_8cpp-source.html b/docs/doxygen/nel/chain__quad_8cpp-source.html new file mode 100644 index 00000000..d732edb2 --- /dev/null +++ b/docs/doxygen/nel/chain__quad_8cpp-source.html @@ -0,0 +1,616 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

chain_quad.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2001 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "stdpacs.h"
+00027 
+00028 #include "pacs/chain_quad.h"
+00029 
+00030 using   namespace std;
+00031 using   namespace NLMISC;
+00032 
+00033 
+00034 namespace NLPACS
+00035 {
+00036 
+00037 
+00038 // ***************************************************************************
+00039 const   float   CChainQuad::_QuadElementSize= 4;        // = 4 meters.
+00040 
+00041 
+00042 // ***************************************************************************
+00043 CChainQuad::CChainQuad()
+00044 {
+00045         _QuadData= NULL;
+00046         _QuadDataLen= 0;
+00047 }
+00048 // ***************************************************************************
+00049 CChainQuad::~CChainQuad()
+00050 {
+00051         delete [] _QuadData;
+00052         _QuadData= NULL;
+00053         _QuadDataLen= 0;
+00054 }
+00055 // ***************************************************************************
+00056 CChainQuad::CChainQuad(const CChainQuad &o)
+00057 {
+00058         _QuadData= NULL;
+00059         _QuadDataLen= 0;
+00060         *this= o;
+00061 }
+00062 // ***************************************************************************
+00063 CChainQuad      &CChainQuad::operator=(const CChainQuad &o)
+00064 {
+00065         // Alloc good quaddata.
+00066         _QuadDataLen= o._QuadDataLen;
+00067         delete [] _QuadData;
+00068         if(_QuadDataLen>0)
+00069         {
+00070                 _QuadData= (uint8*)new uint8[_QuadDataLen];
+00071                 // copy contents.
+00072                 memcpy(_QuadData, o._QuadData, _QuadDataLen);
+00073         }
+00074         else
+00075                 _QuadData= NULL;
+00076 
+00077         // copy infos.
+00078         _Width= o._Width;
+00079         _Height= o._Height;
+00080         _X= o._X;
+00081         _Y= o._Y;
+00082 
+00083         // copy good pointers.
+00084         _Quad.clear();
+00085         _Quad.resize(o._Quad.size(), NULL);
+00086         for(sint i=0; i<(sint)_Quad.size(); i++)
+00087         {
+00088                 if(o._Quad[i])
+00089                 {
+00090                         uint32  off= (uint32)(o._Quad[i]-o._QuadData);
+00091                         _Quad[i]= _QuadData+off;
+00092                 }
+00093         }
+00094 
+00095 
+00096         return *this;
+00097 }
+00098 
+00099 
+00100 
+00101 // ***************************************************************************
+00102 void                    CChainQuad::getGridBounds(sint32 &x0, sint32 &y0, sint32 &x1, sint32 &y1, const CVector &minP, const CVector &maxP) const
+00103 {
+00104         x0= (sint32)floor(minP.x / _QuadElementSize) - _X;
+00105         y0= (sint32)floor(minP.y / _QuadElementSize) - _Y;
+00106         x1= (sint32) ceil(maxP.x / _QuadElementSize) - _X;
+00107         y1= (sint32) ceil(maxP.y / _QuadElementSize) - _Y;
+00108         // Manage selection of a point exactly on a quad bound
+00109         if(x1-x0==0)
+00110                 x0--, x1++;
+00111         if(y1-y0==0)
+00112                 y0--, y1++;
+00113         // clamp
+00114         x0= max(x0, (sint32)0);
+00115         y0= max(y0, (sint32)0);
+00116         x1= min(x1, (sint32)_Width);
+00117         y1= min(y1, (sint32)_Height);
+00118 }
+00119 
+00120 
+00121 // ***************************************************************************
+00122 void                    CChainQuad::build(const std::vector<COrderedChain> &ochains)
+00123 {
+00124         vector< list<CEdgeChainEntry> > tempQuad;
+00125         sint    i,j;
+00126 
+00127         // first, clear any pr-build.
+00128         contReset(_Quad);
+00129         delete [] _QuadData;
+00130         _QuadData= NULL;
+00131         _QuadDataLen= 0;
+00132 
+00133 
+00134         // 0. Find BBox of the grid. Allocate grid.
+00135         //=========================================
+00136         bool            first=true;
+00137         CAABBox         chainquadBBox;
+00138         // run all chains.
+00139         for(i=0;i<(sint)ochains.size();i++)
+00140         {
+00141                 const std::vector<CVector2s>    &vertices= ochains[i].getVertices();
+00142 
+00143                 // run all vertices.
+00144                 for(j= 0; j<(sint)vertices.size();j++)
+00145                 {
+00146                         // enlarge bbox.
+00147                         if(first)
+00148                                 first= false, chainquadBBox.setCenter(vertices[j].unpack3f());
+00149                         else
+00150                                 chainquadBBox.extend(vertices[j].unpack3f());
+00151                 }
+00152         }
+00153 
+00154         // compute X,Y,Width, Height.
+00155         _X= (sint32)floor(chainquadBBox.getMin().x / _QuadElementSize);
+00156         _Y= (sint32)floor(chainquadBBox.getMin().y / _QuadElementSize);
+00157         _Width= (sint32)ceil(chainquadBBox.getMax().x / _QuadElementSize) - _X;
+00158         _Height= (sint32)ceil(chainquadBBox.getMax().y / _QuadElementSize) - _Y;
+00159 
+00160         tempQuad.resize(_Width*_Height);
+00161         _Quad.resize(_Width*_Height, NULL);
+00162 
+00163 
+00164         // 1. For each edge, add them to the quadgrid.
+00165         //=========================================
+00166         // run all chains.
+00167         for(i=0;i<(sint)ochains.size();i++)
+00168         {
+00169                 const std::vector<CVector2s>    &vertices= ochains[i].getVertices();
+00170 
+00171                 sint    numEdges= (sint)vertices.size()-1;
+00172 
+00173                 // run all edges.
+00174                 for(j= 0; j<numEdges; j++)
+00175                 {
+00176                         const CVector           p0= vertices[j].unpack3f();
+00177                         const CVector           p1= vertices[j+1].unpack3f();
+00178                         CVector         minP,maxP;
+00179                         minP.minof(p0, p1);
+00180                         maxP.maxof(p0, p1);
+00181                         // PrecisionPb: extend a little this edge. This is important for special case like borders on zones.
+00182                         if(minP.x-maxP.x==0)
+00183                                 minP.x-=0.001f, maxP.x+=0.001f;
+00184                         if(minP.y-maxP.y==0)
+00185                                 minP.y-=0.001f, maxP.y+=0.001f;
+00186 
+00187 
+00188                         // get bounding coordinate of this edge in the quadgrid.
+00189                         sint32  x0, y0, x1, y1;
+00190                         getGridBounds(x0, y0, x1, y1, minP, maxP);
+00191 
+00192                         // add this edge to all the quadnode it touch.
+00193                         for(sint y= y0; y<y1; y++)
+00194                         {
+00195                                 for(sint x= x0; x<x1; x++)
+00196                                 {
+00197                                         list<CEdgeChainEntry>   &quadNode= tempQuad[y*_Width+x];
+00198 
+00199                                         addEdgeToQuadNode(quadNode, i, j);
+00200                                 }
+00201                         }
+00202                 }
+00203         }
+00204 
+00205 
+00206         // 2. Mem optimisation: Use only 1 block for ALL quads of the grid.
+00207         //=========================================
+00208         sint    memSize= 0;
+00209         // run all quads.
+00210         for(i=0;i<(sint)tempQuad.size();i++)
+00211         {
+00212                 list<CEdgeChainEntry>   &quadNode= tempQuad[i];
+00213 
+00214                 if(!quadNode.empty())
+00215                 {
+00216                         // add an entry for Len.
+00217                         memSize+= sizeof(uint16);
+00218                         // add N entry of CEdgeChainEntry.
+00219                         memSize+= quadNode.size()*sizeof(CEdgeChainEntry);
+00220                 }
+00221         }
+00222 
+00223         // allocate.
+00224         _QuadData= (uint8*)new uint8[memSize];
+00225         _QuadDataLen= memSize;
+00226 
+00227 
+00228         // 3. Fill _QuadData with lists.
+00229         //=========================================
+00230         uint8   *ptr= _QuadData;
+00231         for(i=0;i<(sint)tempQuad.size();i++)
+00232         {
+00233                 list<CEdgeChainEntry>                   &srcQuadNode= tempQuad[i];
+00234                 list<CEdgeChainEntry>::iterator it;
+00235 
+00236                 if(!srcQuadNode.empty())
+00237                 {
+00238                         _Quad[i]= ptr;
+00239 
+00240                         // write len.
+00241                         uint16  len= srcQuadNode.size();
+00242                         *((uint16*)ptr)= len;
+00243                         ptr+= sizeof(uint16);
+00244 
+00245                         // add entries.
+00246                         it= srcQuadNode.begin();
+00247                         for(j=0; j<len; j++, it++)
+00248                         {
+00249                                 *((CEdgeChainEntry*)ptr)= *it;
+00250                                 ptr+= sizeof(CEdgeChainEntry);
+00251                         }
+00252                 }
+00253         }
+00254 
+00255 
+00256         // End.
+00257 }
+00258 
+00259 
+00260 // ***************************************************************************
+00261 void                    CChainQuad::addEdgeToQuadNode(list<CEdgeChainEntry> &quadNode, sint ochainId, sint edgeId)
+00262 {
+00263         // 0. try to find, insert an edge in an existing CEdgeChainEntry.
+00264         //=========================================
+00265         list<CEdgeChainEntry>::iterator         it;
+00266         for(it= quadNode.begin(); it!=quadNode.end();it++)
+00267         {
+00268                 if(it->OChainId==ochainId)
+00269                 {
+00270                         // selection is faster if we only manages a single start/end block.
+00271                         it->EdgeStart= min(it->EdgeStart, (uint16)edgeId);
+00272                         it->EdgeEnd= max(it->EdgeEnd, (uint16)(edgeId+1));
+00273                         return;
+00274                 }
+00275         }
+00276 
+00277 
+00278         // 1. else, create new one.
+00279         //=========================================
+00280         CEdgeChainEntry         entry;
+00281         entry.OChainId= ochainId;
+00282         entry.EdgeStart= edgeId;
+00283         entry.EdgeEnd= edgeId+1;
+00284         quadNode.push_back(entry);
+00285 }
+00286 
+00287 
+00288 // ***************************************************************************
+00289 sint                    CChainQuad::selectEdges(const NLMISC::CAABBox &bbox, CCollisionSurfaceTemp &cst) const
+00290 {
+00291         sint    nRes=0;
+00292         sint    i;
+00293         uint16  *ochainLUT= cst.OChainLUT;
+00294 
+00295         // start: no edge found.
+00296         cst.EdgeChainEntries.clear();
+00297 
+00298         // get bounding coordinate of this bbox in the quadgrid.
+00299         sint32  x0, y0, x1, y1;
+00300         getGridBounds(x0, y0, x1, y1, bbox.getMin(), bbox.getMax());
+00301 
+00302 
+00303         // run all intersected quads.
+00304         for(sint y= y0; y<y1; y++)
+00305         {
+00306                 for(sint x= x0; x<x1; x++)
+00307                 {
+00308                         uint8   *quadNode= _Quad[y*_Width+x];
+00309 
+00310                         // no edgechain entry??
+00311                         if(!quadNode)
+00312                                 continue;
+00313 
+00314                         // get edgechain entries
+00315                         sint    numEdgeChainEntries= *((uint16*)quadNode);
+00316                         quadNode+= sizeof(uint16);
+00317                         CEdgeChainEntry         *ptrEdgeChainEntry= (CEdgeChainEntry*)quadNode;
+00318 
+00319                         // For each one, add it to the result list.
+00320                         for(i=0;i<numEdgeChainEntries;i++)
+00321                         {
+00322                                 uint16  ochainId= ptrEdgeChainEntry[i].OChainId;
+00323 
+00324                                 // if ochain not yet inserted.
+00325                                 if(ochainLUT[ochainId]==0xFFFF)
+00326                                 {
+00327                                         // inc the list.
+00328                                         ochainLUT[ochainId]= nRes;
+00329                                         cst.EdgeChainEntries.push_back(ptrEdgeChainEntry[i]);
+00330                                         nRes++;
+00331                                 }
+00332                                 else
+00333                                 {
+00334                                         // extend the entry in the list.
+00335                                         uint16 id= ochainLUT[ochainId];
+00336                                         CEdgeChainEntry         &ece= cst.EdgeChainEntries[id];
+00337                                         ece.EdgeStart= min(ece.EdgeStart, ptrEdgeChainEntry[i].EdgeStart);
+00338                                         ece.EdgeEnd= max(ece.EdgeEnd, ptrEdgeChainEntry[i].EdgeEnd);
+00339                                 }
+00340                         }
+00341                 }
+00342         }
+00343 
+00344 
+00345         // reset LUT to 0xFFFF for all ochains selected.
+00346         for(i=0;i<nRes;i++)
+00347         {
+00348                 uint16  ochainId= cst.EdgeChainEntries[i].OChainId;
+00349                 ochainLUT[ochainId]= 0xFFFF;
+00350         }
+00351 
+00352 
+00353         return nRes;
+00354 }
+00355 
+00356 sint            CChainQuad::selectEdges(CVector start, CVector end, CCollisionSurfaceTemp &cst) const
+00357 {
+00358         sint    nRes=0;
+00359         sint    i;
+00360         uint16  *ochainLUT= cst.OChainLUT;
+00361 
+00362         // start: no edge found.
+00363         cst.EdgeChainEntries.clear();
+00364 
+00365         if (end.x < start.x)
+00366                 swap(start, end);
+00367 
+00368         float   minx = _X*_QuadElementSize,
+00369                         miny = _Y*_QuadElementSize,
+00370                         maxx = minx + _Width*_QuadElementSize,
+00371                         maxy = miny + _Height*_QuadElementSize;
+00372 
+00373         if (start.x > maxx || end.x < minx || start.y > maxy || end.y < miny)
+00374                 return nRes;
+00375 
+00376         if (start.x < minx)
+00377         {
+00378                 start.y = start.y+(end.y-start.y)*(minx-start.x)/(end.x-start.x);
+00379                 start.x = minx;
+00380         }
+00381 
+00382         if (start.y < miny)
+00383         {
+00384                 start.x = start.x+(end.x-start.x)*(miny-start.y)/(end.y-start.y);
+00385                 start.y = miny;
+00386         }
+00387 
+00388         if (end.x > maxx)
+00389         {
+00390                 end.y = start.y+(end.y-start.y)*(minx-start.x)/(end.x-start.x);
+00391                 end.x = maxx;
+00392         }
+00393 
+00394         if (end.y > maxy)
+00395         {
+00396                 end.x = start.x+(end.x-start.x)*(miny-start.y)/(end.y-start.y);
+00397                 end.y = maxy;
+00398         }
+00399 
+00400         sint32  x0, x1, ya, yb;
+00401         sint    x, y;
+00402         float   fx, fxa, fxb, fya, fyb;
+00403 
+00404         x0 = (sint32)floor(start.x / _QuadElementSize) - _X;
+00405         x1 = (sint32)ceil(end.x / _QuadElementSize) - _X;
+00406         fx = (x0+_X)*_QuadElementSize;
+00407 
+00408         for (x=x0; x<x1; ++x)
+00409         {
+00410                 fxa = (fx < start.x) ? start.x : fx;
+00411                 fxb = (fx+_QuadElementSize > end.x) ? end.x : fx+_QuadElementSize;
+00412 
+00413                 fya = start.y+(end.y-start.y)*(fxa-start.x)/(end.x-start.x);
+00414                 fyb = start.y+(end.y-start.y)*(fxb-start.x)/(end.x-start.x);
+00415 
+00416                 if (fya > fyb)
+00417                         swap (fya, fyb);
+00418 
+00419                 ya = (sint32)floor(fya / _QuadElementSize) - _Y;
+00420                 yb = (sint32)ceil(fyb / _QuadElementSize) - _Y;
+00421 
+00422                 fx += _QuadElementSize;
+00423 
+00424                 for (y=ya; y<yb; ++y)
+00425                 {
+00426                         uint8   *quadNode= _Quad[y*_Width+x];
+00427 
+00428                         // no edgechain entry??
+00429                         if(!quadNode)
+00430                                 continue;
+00431 
+00432                         // get edgechain entries
+00433                         sint    numEdgeChainEntries= *((uint16*)quadNode);
+00434                         quadNode+= sizeof(uint16);
+00435                         CEdgeChainEntry         *ptrEdgeChainEntry= (CEdgeChainEntry*)quadNode;
+00436 
+00437                         // For each one, add it to the result list.
+00438                         for(i=0;i<numEdgeChainEntries;i++)
+00439                         {
+00440                                 uint16  ochainId= ptrEdgeChainEntry[i].OChainId;
+00441 
+00442                                 // if ochain not yet inserted.
+00443                                 if(ochainLUT[ochainId]==0xFFFF)
+00444                                 {
+00445                                         // inc the list.
+00446                                         ochainLUT[ochainId]= nRes;
+00447                                         cst.EdgeChainEntries.push_back(ptrEdgeChainEntry[i]);
+00448                                         nRes++;
+00449                                 }
+00450                                 else
+00451                                 {
+00452                                         // extend the entry in the list.
+00453                                         uint16 id= ochainLUT[ochainId];
+00454                                         CEdgeChainEntry         &ece= cst.EdgeChainEntries[id];
+00455                                         ece.EdgeStart= min(ece.EdgeStart, ptrEdgeChainEntry[i].EdgeStart);
+00456                                         ece.EdgeEnd= max(ece.EdgeEnd, ptrEdgeChainEntry[i].EdgeEnd);
+00457                                 }
+00458                         }
+00459                 }
+00460         }
+00461 
+00462         // reset LUT to 0xFFFF for all ochains selected.
+00463         for(i=0;i<nRes;i++)
+00464         {
+00465                 uint16  ochainId= cst.EdgeChainEntries[i].OChainId;
+00466                 ochainLUT[ochainId]= 0xFFFF;
+00467         }
+00468 
+00469         return nRes;
+00470 }
+00471 
+00472 // ***************************************************************************
+00473 void            CChainQuad::serial(NLMISC::IStream &f)
+00474 {
+00475         /*
+00476         Version 0:
+00477                 - base version.
+00478         */
+00479         (void)f.serialVersion(0);
+00480         uint    i;
+00481 
+00482         // serial basics.
+00483         f.serial(_X, _Y, _Width, _Height, _QuadDataLen);
+00484 
+00485 
+00486         // serial _QuadData.
+00487         if(f.isReading())
+00488         {
+00489                 delete [] _QuadData;
+00490                 if(_QuadDataLen>0)
+00491                         _QuadData= (uint8*)new uint8[_QuadDataLen];
+00492                 else
+00493                         _QuadData= NULL;
+00494         }
+00495         // Since we have only uint16 (see CEdgeChainEntry), serial them in a single block.
+00496         uint16  *ptrQData= (uint16*)_QuadData;
+00497         for(i=0;i<_QuadDataLen/2; i++, ptrQData++)
+00498         {
+00499                 f.serial(*ptrQData);
+00500         }
+00501 
+00502 
+00503         // serial _Quad.
+00504         std::vector<uint32>             offsets;
+00505         uint32          len;
+00506         uint32          val;
+00507         if(f.isReading())
+00508         {
+00509                 // len/resize.
+00510                 f.serial(len);
+00511                 offsets.resize(len);
+00512                 contReset(_Quad);
+00513                 _Quad.resize(len);
+00514 
+00515                 // read offsets -> ptrs.
+00516                 for(i=0; i<len; i++)
+00517                 {
+00518                         f.serial(val);
+00519                         if(val== 0xFFFFFFFF)
+00520                                 _Quad[i]= NULL;
+00521                         else
+00522                                 _Quad[i]= _QuadData+val;
+00523                 }
+00524         }
+00525         else
+00526         {
+00527                 // len/resize.
+00528                 len= _Quad.size();
+00529                 f.serial(len);
+00530 
+00531                 // write offsets.
+00532                 for(i=0; i<len; i++)
+00533                 {
+00534                         uint8   *ptr= _Quad[i];
+00535                         if(ptr==NULL)
+00536                                 val= 0xFFFFFFFF;
+00537                         else
+00538                                 val= (uint32)(ptr-_QuadData);
+00539                         f.serial(val);
+00540                 }
+00541         }
+00542 
+00543 }
+00544 
+00545 
+00546 
+00547 } // NLPACS
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1