$search
00001 #include <stdio.h> 00002 #include <stdlib.h> 00003 #include <string.h> 00004 #include <assert.h> 00005 00006 #pragma warning(disable:4786) 00007 00008 #include <vector> 00009 #include <map> 00010 #include <set> 00068 // CodeSnippet provided by John W. Ratcliff 00069 // on March 23, 2006. 00070 // 00071 // mailto: jratcliff@infiniplex.net 00072 // 00073 // Personal website: http://jratcliffscarab.blogspot.com 00074 // Coding Website: http://codesuppository.blogspot.com 00075 // FundRaising Blog: http://amillionpixels.blogspot.com 00076 // Fundraising site: http://www.amillionpixels.us 00077 // New Temple Site: http://newtemple.blogspot.com 00078 // 00079 // This snippet shows how to 'hide' the complexity of 00080 // the STL by wrapping some useful piece of functionality 00081 // around a handful of discrete API calls. 00082 // 00083 // This API allows you to create an indexed triangle list 00084 // from a collection of raw input triangles. Internally 00085 // it uses an STL set to build the lookup table very rapidly. 00086 // 00087 // Here is how you would use it to build an indexed triangle 00088 // list from a raw list of triangles. 00089 // 00090 // (1) create a 'VertexLookup' interface by calling 00091 // 00092 // VertexLook vl = Vl_createVertexLookup(); 00093 // 00094 // (2) For each vertice in each triangle call: 00095 // 00096 // unsigned int i1 = Vl_getIndex(vl,p1); 00097 // unsigned int i2 = Vl_getIndex(vl,p2); 00098 // unsigned int i3 = Vl_getIndex(vl,p3); 00099 // 00100 // save the 3 indices into your triangle list array. 00101 // 00102 // (3) Get the vertex array by calling: 00103 // 00104 // const double *vertices = Vl_getVertices(vl); 00105 // 00106 // (4) Get the number of vertices so you can copy them into 00107 // your own buffer. 00108 // unsigned int vcount = Vl_getVcount(vl); 00109 // 00110 // (5) Release the VertexLookup interface when you are done with it. 00111 // Vl_releaseVertexLookup(vl); 00112 // 00113 // Teaches the following lessons: 00114 // 00115 // How to wrap the complexity of STL and C++ classes around a 00116 // simple API interface. 00117 // 00118 // How to use an STL set and custom comparator operator for 00119 // a complex data type. 00120 // 00121 // How to create a template class. 00122 // 00123 // How to achieve significant performance improvements by 00124 // taking advantage of built in STL containers in just 00125 // a few lines of code. 00126 // 00127 // You could easily modify this code to support other vertex 00128 // formats with any number of interpolants. 00129 00130 00131 00132 00133 #include "vlookup.h" 00134 00135 namespace ConvexDecomposition 00136 { 00137 00138 class VertexPosition 00139 { 00140 public: 00141 VertexPosition(void) { }; 00142 VertexPosition(const double *p) 00143 { 00144 mPos[0] = p[0]; 00145 mPos[1] = p[1]; 00146 mPos[2] = p[2]; 00147 }; 00148 00149 void Set(int index,const double *pos) 00150 { 00151 const double * p = &pos[index*3]; 00152 00153 mPos[0] = p[0]; 00154 mPos[1] = p[1]; 00155 mPos[2] = p[2]; 00156 00157 }; 00158 00159 double GetX(void) const { return mPos[0]; }; 00160 double GetY(void) const { return mPos[1]; }; 00161 double GetZ(void) const { return mPos[2]; }; 00162 00163 double mPos[3]; 00164 }; 00165 00166 00167 template <typename Type> class VertexLess 00168 { 00169 public: 00170 typedef std::vector< Type > VertexVector; 00171 00172 bool operator()(int v1,int v2) const; 00173 00174 static void SetSearch(const Type& match,VertexVector *list) 00175 { 00176 mFind = match; 00177 mList = list; 00178 }; 00179 00180 private: 00181 const Type& Get(int index) const 00182 { 00183 if ( index == -1 ) return mFind; 00184 VertexVector &vlist = *mList; 00185 return vlist[index]; 00186 } 00187 static Type mFind; // vertice to locate. 00188 static VertexVector *mList; 00189 }; 00190 00191 template <typename Type> class VertexPool 00192 { 00193 public: 00194 typedef std::set<int, VertexLess<Type> > VertexSet; 00195 typedef std::vector< Type > VertexVector; 00196 00197 int GetVertex(const Type& vtx) 00198 { 00199 VertexLess<Type>::SetSearch(vtx,&mVtxs); 00200 typename VertexSet::iterator found; 00201 found = mVertSet.find( -1 ); 00202 if ( found != mVertSet.end() ) 00203 { 00204 return *found; 00205 } 00206 int idx = (int)mVtxs.size(); 00207 mVtxs.push_back( vtx ); 00208 mVertSet.insert( idx ); 00209 return idx; 00210 }; 00211 00212 const double * GetPos(int idx) const 00213 { 00214 return mVtxs[idx].mPos; 00215 } 00216 00217 const Type& Get(int idx) const 00218 { 00219 return mVtxs[idx]; 00220 }; 00221 00222 unsigned int GetSize(void) const 00223 { 00224 return mVtxs.size(); 00225 }; 00226 00227 void Clear(int reservesize) // clear the vertice pool. 00228 { 00229 mVertSet.clear(); 00230 mVtxs.clear(); 00231 mVtxs.reserve(reservesize); 00232 }; 00233 00234 const VertexVector& GetVertexList(void) const { return mVtxs; }; 00235 00236 void Set(const Type& vtx) 00237 { 00238 mVtxs.push_back(vtx); 00239 } 00240 00241 unsigned int GetVertexCount(void) const 00242 { 00243 return mVtxs.size(); 00244 }; 00245 00246 00247 Type * GetBuffer(void) 00248 { 00249 return &mVtxs[0]; 00250 }; 00251 00252 private: 00253 VertexSet mVertSet; // ordered list. 00254 VertexVector mVtxs; // set of vertices. 00255 }; 00256 00257 double tmpp[3] = {0,0,0}; 00258 template<> VertexPosition VertexLess<VertexPosition>::mFind = tmpp; 00259 template<> std::vector<VertexPosition > *VertexLess<VertexPosition>::mList =0; 00260 00261 enum RDIFF 00262 { 00263 RD_EQUAL, 00264 RD_LESS, 00265 RD_GREATER 00266 }; 00267 00268 static RDIFF relativeDiff(const double *a,const double *b,double magnitude) 00269 { 00270 RDIFF ret = RD_EQUAL; 00271 00272 double m2 = magnitude*magnitude; 00273 double dx = a[0]-b[0]; 00274 double dy = a[1]-b[1]; 00275 double dz = a[2]-b[2]; 00276 double d2 = (dx*dx)+(dy*dy)+(dz*dz); 00277 00278 if ( d2 > m2 ) 00279 { 00280 if ( a[0] < b[0] ) ret = RD_LESS; 00281 else if ( a[0] > b[0] ) ret = RD_GREATER; 00282 else if ( a[1] < b[1] ) ret = RD_LESS; 00283 else if ( a[1] > b[1] ) ret = RD_GREATER; 00284 else if ( a[2] < b[2] ) ret = RD_LESS; 00285 else if ( a[2] > b[2] ) ret = RD_GREATER; 00286 } 00287 return ret; 00288 } 00289 00290 00291 template<> 00292 bool VertexLess<VertexPosition>::operator()(int v1,int v2) const 00293 { 00294 bool ret = false; 00295 00296 const VertexPosition& a = Get(v1); 00297 const VertexPosition& b = Get(v2); 00298 00299 RDIFF d = relativeDiff(a.mPos,b.mPos,0.0001f); 00300 if ( d == RD_LESS ) ret = true; 00301 00302 return ret; 00303 00304 }; 00305 00306 00307 00308 VertexLookup Vl_createVertexLookup(void) 00309 { 00310 VertexLookup ret = new VertexPool< VertexPosition >; 00311 return ret; 00312 } 00313 00314 void Vl_releaseVertexLookup(VertexLookup vlook) 00315 { 00316 VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; 00317 delete vp; 00318 } 00319 00320 unsigned int Vl_getIndex(VertexLookup vlook,const double *pos) // get index. 00321 { 00322 VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; 00323 VertexPosition p(pos); 00324 return vp->GetVertex(p); 00325 } 00326 00327 const double * Vl_getVertices(VertexLookup vlook) 00328 { 00329 VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; 00330 return vp->GetPos(0); 00331 } 00332 00333 00334 unsigned int Vl_getVcount(VertexLookup vlook) 00335 { 00336 VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; 00337 return vp->GetVertexCount(); 00338 } 00339 00340 }; // end of namespace