00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_FACE_GRID_H
00027 #define NL_FACE_GRID_H
00028
00029 #include <vector>
00030 #include "nel/misc/types_nl.h"
00031 #include "nel/misc/vector.h"
00032 #include "nel/misc/file.h"
00033
00034 #include "nel/misc/aabbox.h"
00035
00036 #include "pacs/vector_2s.h"
00037 #include "pacs/surface_quad.h"
00038 #include "pacs/chain.h"
00039 #include "pacs/retrievable_surface.h"
00040 #include "pacs/chain_quad.h"
00041 #include "pacs/exterior_mesh.h"
00042 #include "pacs/quad_grid.h"
00043
00044 #include "nel/pacs/u_global_position.h"
00045
00046
00047
00048 namespace NLPACS
00049 {
00050
00057 class CFaceGrid
00058 {
00059 public:
00066 class CFaceGridBuild
00067 {
00068 public:
00070 std::vector< std::vector<uint32> > Grid;
00071
00073 uint Width;
00074
00076 float Size;
00077
00078 public:
00080 void init(uint width, float elsize);
00081
00083 void insert(const NLMISC::CVector &bmin, const NLMISC::CVector &bmax, uint32 value);
00084 };
00085
00086 protected:
00088 uint16 _Width;
00090 uint16 _Log2Width;
00091
00093 float _ElSize;
00094
00096 std::vector<uint32> _Grid;
00098 std::vector<uint32> _GridData;
00099
00100 public:
00102 CFaceGrid() : _Width(0), _Log2Width(0), _ElSize(0.0f) {}
00103
00104
00106 void clear();
00107
00109 void create(const CFaceGridBuild &fgb);
00110
00112 void select(const NLMISC::CVector &pos, std::vector<uint32> &selected) const;
00113
00115 void serial(NLMISC::IStream &f);
00116 };
00117
00118
00119
00120 inline void CFaceGrid::clear()
00121 {
00122 _Width = 0;
00123 _Log2Width = 0;
00124 _ElSize = 0.0f;
00125 _Grid.clear();
00126 _GridData.clear();
00127 }
00128
00129 inline void CFaceGrid::create(const CFaceGrid::CFaceGridBuild &fgb)
00130 {
00131 nlassert(fgb.Grid.size() == fgb.Width*fgb.Width);
00132 nlassert(fgb.Width < 32768);
00133
00134
00135 clear();
00136
00137
00138 _Width = (uint16)fgb.Width;
00139 _ElSize = fgb.Size;
00140 _Log2Width = NLMISC::getPowerOf2(_Width);
00141
00142
00143 uint i;
00144 for (i=0; i<fgb.Grid.size(); ++i)
00145 {
00146 _Grid.push_back(_GridData.size());
00147 _GridData.insert(_GridData.end(), fgb.Grid[i].begin(), fgb.Grid[i].end());
00148 }
00149 }
00150
00151 inline void CFaceGrid::select(const NLMISC::CVector &pos, std::vector<uint32> &selected) const
00152 {
00153 selected.clear();
00154
00155 uint start, stop, idx;
00156 uint x, y;
00157
00158 x = ((sint)(pos.x/_ElSize) & (_Width-1));
00159 y = ((sint)(pos.y/_ElSize) & (_Width-1));
00160
00161 idx = x+(y<<_Log2Width);
00162
00163 start = _Grid[idx++];
00164 stop = (idx == _Grid.size()) ? _GridData.size() : _Grid[idx];
00165
00166 for (; start<stop; ++start)
00167 selected.push_back(_GridData[start]);
00168 }
00169
00170 inline void CFaceGrid::serial(NLMISC::IStream &f)
00171 {
00172
00173
00174
00175
00176 (void)f.serialVersion(0);
00177
00178 f.serial(_Width, _Log2Width, _ElSize);
00179 f.serialCont(_Grid);
00180 f.serialCont(_GridData);
00181 }
00182
00183
00184
00185
00186
00187 inline void CFaceGrid::CFaceGridBuild::init(uint width, float elsize)
00188 {
00189 nlassert(NLMISC::isPowerOf2(width));
00190 Width = width;
00191 Size = elsize;
00192 Grid.clear();
00193 Grid.resize(Width*Width);
00194 }
00195
00196 inline void CFaceGrid::CFaceGridBuild::insert(const NLMISC::CVector &bmin,
00197 const NLMISC::CVector &bmax,
00198 uint32 value)
00199 {
00200 sint x0 = (sint)(bmin.x/Size),
00201 x1 = (sint)(bmax.x/Size),
00202 y0 = (sint)(bmin.y/Size),
00203 y1 = (sint)(bmax.y/Size);
00204
00205 if (x1-x0 >= (sint)Width)
00206 {
00207 x0 = 0;
00208 x1 = Width-1;
00209 }
00210 else
00211 {
00212 x0 &= (Width-1);
00213 x1 &= (Width-1);
00214 if (x1 < x0)
00215 x1 += Width;
00216 }
00217
00218 if (y1-y0 >= (sint)Width)
00219 {
00220 y0 = 0;
00221 y1 = Width-1;
00222 }
00223 else
00224 {
00225 y0 &= (Width-1);
00226 y1 &= (Width-1);
00227 if (y1 < y0)
00228 y1 += Width;
00229 }
00230
00231 sint x, y;
00232
00233 for (y=y0; y<=y1; ++y)
00234 for (x=x0; x<=x1; ++x)
00235 Grid[(x&(Width-1))+(y&(Width-1))*Width].push_back(value);
00236 }
00237
00238
00239 };
00240
00241 #endif // NL_FACE_GRID_H
00242
00243