Planeshift
|
00001 // 00002 // Copyright (c) 2009-2010 Mikko Mononen [email protected] 00003 // 00004 // This software is provided 'as-is', without any express or implied 00005 // warranty. In no event will the authors be held liable for any damages 00006 // arising from the use of this software. 00007 // Permission is granted to anyone to use this software for any purpose, 00008 // including commercial applications, and to alter it and redistribute it 00009 // freely, subject to the following restrictions: 00010 // 1. The origin of this software must not be misrepresented; you must not 00011 // claim that you wrote the original software. If you use this software 00012 // in a product, an acknowledgment in the product documentation would be 00013 // appreciated but is not required. 00014 // 2. Altered source versions must be plainly marked as such, and must not be 00015 // misrepresented as being the original software. 00016 // 3. This notice may not be removed or altered from any source distribution. 00017 // 00018 00019 #ifndef DETOURCOMMON_H 00020 #define DETOURCOMMON_H 00021 00032 00033 00034 00038 template<class T> inline void dtSwap(T& a, T& b) { T t = a; a = b; b = t; } 00039 00044 template<class T> inline T dtMin(T a, T b) { return a < b ? a : b; } 00045 00050 template<class T> inline T dtMax(T a, T b) { return a > b ? a : b; } 00051 00055 template<class T> inline T dtAbs(T a) { return a < 0 ? -a : a; } 00056 00060 template<class T> inline T dtSqr(T a) { return a*a; } 00061 00067 template<class T> inline T dtClamp(T v, T mn, T mx) { return v < mn ? mn : (v > mx ? mx : v); } 00068 00072 float dtSqrt(float x); 00073 00077 00082 inline void dtVcross(float* dest, const float* v1, const float* v2) 00083 { 00084 dest[0] = v1[1]*v2[2] - v1[2]*v2[1]; 00085 dest[1] = v1[2]*v2[0] - v1[0]*v2[2]; 00086 dest[2] = v1[0]*v2[1] - v1[1]*v2[0]; 00087 } 00088 00093 inline float dtVdot(const float* v1, const float* v2) 00094 { 00095 return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; 00096 } 00097 00103 inline void dtVmad(float* dest, const float* v1, const float* v2, const float s) 00104 { 00105 dest[0] = v1[0]+v2[0]*s; 00106 dest[1] = v1[1]+v2[1]*s; 00107 dest[2] = v1[2]+v2[2]*s; 00108 } 00109 00115 inline void dtVlerp(float* dest, const float* v1, const float* v2, const float t) 00116 { 00117 dest[0] = v1[0]+(v2[0]-v1[0])*t; 00118 dest[1] = v1[1]+(v2[1]-v1[1])*t; 00119 dest[2] = v1[2]+(v2[2]-v1[2])*t; 00120 } 00121 00126 inline void dtVadd(float* dest, const float* v1, const float* v2) 00127 { 00128 dest[0] = v1[0]+v2[0]; 00129 dest[1] = v1[1]+v2[1]; 00130 dest[2] = v1[2]+v2[2]; 00131 } 00132 00137 inline void dtVsub(float* dest, const float* v1, const float* v2) 00138 { 00139 dest[0] = v1[0]-v2[0]; 00140 dest[1] = v1[1]-v2[1]; 00141 dest[2] = v1[2]-v2[2]; 00142 } 00143 00148 inline void dtVscale(float* dest, const float* v, const float t) 00149 { 00150 dest[0] = v[0]*t; 00151 dest[1] = v[1]*t; 00152 dest[2] = v[2]*t; 00153 } 00154 00158 inline void dtVmin(float* mn, const float* v) 00159 { 00160 mn[0] = dtMin(mn[0], v[0]); 00161 mn[1] = dtMin(mn[1], v[1]); 00162 mn[2] = dtMin(mn[2], v[2]); 00163 } 00164 00168 inline void dtVmax(float* mx, const float* v) 00169 { 00170 mx[0] = dtMax(mx[0], v[0]); 00171 mx[1] = dtMax(mx[1], v[1]); 00172 mx[2] = dtMax(mx[2], v[2]); 00173 } 00174 00180 inline void dtVset(float* dest, const float x, const float y, const float z) 00181 { 00182 dest[0] = x; dest[1] = y; dest[2] = z; 00183 } 00184 00188 inline void dtVcopy(float* dest, const float* a) 00189 { 00190 dest[0] = a[0]; 00191 dest[1] = a[1]; 00192 dest[2] = a[2]; 00193 } 00194 00198 inline float dtVlen(const float* v) 00199 { 00200 return dtSqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); 00201 } 00202 00206 inline float dtVlenSqr(const float* v) 00207 { 00208 return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; 00209 } 00210 00215 inline float dtVdist(const float* v1, const float* v2) 00216 { 00217 const float dx = v2[0] - v1[0]; 00218 const float dy = v2[1] - v1[1]; 00219 const float dz = v2[2] - v1[2]; 00220 return dtSqrt(dx*dx + dy*dy + dz*dz); 00221 } 00222 00227 inline float dtVdistSqr(const float* v1, const float* v2) 00228 { 00229 const float dx = v2[0] - v1[0]; 00230 const float dy = v2[1] - v1[1]; 00231 const float dz = v2[2] - v1[2]; 00232 return dx*dx + dy*dy + dz*dz; 00233 } 00234 00241 inline float dtVdist2D(const float* v1, const float* v2) 00242 { 00243 const float dx = v2[0] - v1[0]; 00244 const float dz = v2[2] - v1[2]; 00245 return dtSqrt(dx*dx + dz*dz); 00246 } 00247 00252 inline float dtVdist2DSqr(const float* v1, const float* v2) 00253 { 00254 const float dx = v2[0] - v1[0]; 00255 const float dz = v2[2] - v1[2]; 00256 return dx*dx + dz*dz; 00257 } 00258 00261 inline void dtVnormalize(float* v) 00262 { 00263 float d = 1.0f / dtSqrt(dtSqr(v[0]) + dtSqr(v[1]) + dtSqr(v[2])); 00264 v[0] *= d; 00265 v[1] *= d; 00266 v[2] *= d; 00267 } 00268 00276 inline bool dtVequal(const float* p0, const float* p1) 00277 { 00278 static const float thr = dtSqr(1.0f/16384.0f); 00279 const float d = dtVdistSqr(p0, p1); 00280 return d < thr; 00281 } 00282 00289 inline float dtVdot2D(const float* u, const float* v) 00290 { 00291 return u[0]*v[0] + u[2]*v[2]; 00292 } 00293 00300 inline float dtVperp2D(const float* u, const float* v) 00301 { 00302 return u[2]*v[0] - u[0]*v[2]; 00303 } 00304 00308 00314 inline float dtTriArea2D(const float* a, const float* b, const float* c) 00315 { 00316 const float abx = b[0] - a[0]; 00317 const float abz = b[2] - a[2]; 00318 const float acx = c[0] - a[0]; 00319 const float acz = c[2] - a[2]; 00320 return acx*abz - abx*acz; 00321 } 00322 00330 inline bool dtOverlapQuantBounds(const unsigned short amin[3], const unsigned short amax[3], 00331 const unsigned short bmin[3], const unsigned short bmax[3]) 00332 { 00333 bool overlap = true; 00334 overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap; 00335 overlap = (amin[1] > bmax[1] || amax[1] < bmin[1]) ? false : overlap; 00336 overlap = (amin[2] > bmax[2] || amax[2] < bmin[2]) ? false : overlap; 00337 return overlap; 00338 } 00339 00347 inline bool dtOverlapBounds(const float* amin, const float* amax, 00348 const float* bmin, const float* bmax) 00349 { 00350 bool overlap = true; 00351 overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap; 00352 overlap = (amin[1] > bmax[1] || amax[1] < bmin[1]) ? false : overlap; 00353 overlap = (amin[2] > bmax[2] || amax[2] < bmin[2]) ? false : overlap; 00354 return overlap; 00355 } 00356 00363 void dtClosestPtPointTriangle(float* closest, const float* p, 00364 const float* a, const float* b, const float* c); 00365 00372 bool dtClosestHeightPointTriangle(const float* p, const float* a, const float* b, const float* c, float& h); 00373 00374 bool dtIntersectSegmentPoly2D(const float* p0, const float* p1, 00375 const float* verts, int nverts, 00376 float& tmin, float& tmax, 00377 int& segMin, int& segMax); 00378 00384 bool dtPointInPolygon(const float* pt, const float* verts, const int nverts); 00385 00386 bool dtDistancePtPolyEdgesSqr(const float* pt, const float* verts, const int nverts, 00387 float* ed, float* et); 00388 00389 float dtDistancePtSegSqr2D(const float* pt, const float* p, const float* q, float& t); 00390 00396 void dtCalcPolyCenter(float* tc, const unsigned short* idx, int nidx, const float* verts); 00397 00404 bool dtOverlapPolyPoly2D(const float* polya, const int npolya, 00405 const float* polyb, const int npolyb); 00406 00410 00411 inline unsigned int dtNextPow2(unsigned int v) 00412 { 00413 v--; 00414 v |= v >> 1; 00415 v |= v >> 2; 00416 v |= v >> 4; 00417 v |= v >> 8; 00418 v |= v >> 16; 00419 v++; 00420 return v; 00421 } 00422 00423 inline unsigned int dtIlog2(unsigned int v) 00424 { 00425 unsigned int r; 00426 unsigned int shift; 00427 r = (v > 0xffff) << 4; v >>= r; 00428 shift = (v > 0xff) << 3; v >>= shift; r |= shift; 00429 shift = (v > 0xf) << 2; v >>= shift; r |= shift; 00430 shift = (v > 0x3) << 1; v >>= shift; r |= shift; 00431 r |= (v >> 1); 00432 return r; 00433 } 00434 00435 inline int dtAlign4(int x) { return (x+3) & ~3; } 00436 00437 inline int dtOppositeTile(int side) { return (side+4) & 0x7; } 00438 00439 inline void dtSwapByte(unsigned char* a, unsigned char* b) 00440 { 00441 unsigned char tmp = *a; 00442 *a = *b; 00443 *b = tmp; 00444 } 00445 00446 inline void dtSwapEndian(unsigned short* v) 00447 { 00448 unsigned char* x = (unsigned char*)v; 00449 dtSwapByte(x+0, x+1); 00450 } 00451 00452 inline void dtSwapEndian(short* v) 00453 { 00454 unsigned char* x = (unsigned char*)v; 00455 dtSwapByte(x+0, x+1); 00456 } 00457 00458 inline void dtSwapEndian(unsigned int* v) 00459 { 00460 unsigned char* x = (unsigned char*)v; 00461 dtSwapByte(x+0, x+3); dtSwapByte(x+1, x+2); 00462 } 00463 00464 inline void dtSwapEndian(int* v) 00465 { 00466 unsigned char* x = (unsigned char*)v; 00467 dtSwapByte(x+0, x+3); dtSwapByte(x+1, x+2); 00468 } 00469 00470 inline void dtSwapEndian(float* v) 00471 { 00472 unsigned char* x = (unsigned char*)v; 00473 dtSwapByte(x+0, x+3); dtSwapByte(x+1, x+2); 00474 } 00475 00476 void dtRandomPointInConvexPoly(const float* pts, const int npts, float* areas, 00477 const float s, const float t, float* out); 00478 00480 00481 #endif // DETOURCOMMON_H 00482 00484 00485 // This section contains detailed documentation for members that don't have 00486 // a source file. It reduces clutter in the main section of the header. 00487