00001 #ifndef GEOM_HPP 00002 #define GEOM_HPP 00003 00004 #include "Vector3.hpp" 00005 #include "Vector2.hpp" 00006 #include "TriBoxOverlap.hpp" 00007 #include <vector> 00008 00009 #ifndef Vector3i 00010 typedef Vector3T<int> Vector3i; 00011 #endif 00012 00013 class DTraverser 00014 { 00015 public: 00016 DTraverser(const Vector3& pos, const Vector3& dir) 00017 { 00018 p = pos; 00019 d = dir; 00020 d.normalize(); 00021 d/=100.0; 00022 ipos = pos; 00023 } 00024 00025 00026 void next() 00027 { 00028 Vector3i newPos = ipos; 00029 while(newPos == ipos) 00030 { 00031 p += d; 00032 newPos = p; 00033 } 00034 ipos = newPos; 00035 } 00036 00037 Vector3i getPos() { return ipos; } 00038 private: 00039 Vector3i ipos; 00040 Vector3 p; 00041 Vector3 d; 00042 }; 00043 00044 00045 class Traverser 00046 { 00047 public: 00048 Traverser() {} 00049 00050 Traverser(const Vector3& pos, const Vector3& dir) 00051 { 00052 init(pos,dir); 00053 } 00054 00055 void init(const Vector3& pos, const Vector3& dir) 00056 { 00057 ipos = pos; 00058 if(dir.x > 0) 00059 { tMax.x = (ceil(pos.x)-pos.x)/dir.x; step.x = 1; } 00060 else 00061 { tMax.x = (floor(pos.x)-pos.x)/dir.x; step.x = -1; } 00062 00063 if(dir.y > 0) 00064 { tMax.y = (ceil(pos.y)-pos.y)/dir.y; step.y = 1; } 00065 else 00066 { tMax.y = (floor(pos.y)-pos.y)/dir.y; step.y = -1;} 00067 00068 if(dir.z > 0) 00069 { tMax.z = (ceil(pos.z)-pos.z)/dir.z; step.z = 1; } 00070 else 00071 { tMax.z = (floor(pos.z)-pos.z)/dir.z; step.z = -1; } 00072 00073 tDelta.x = fabs(1.0/dir.x); 00074 tDelta.y = fabs(1.0/dir.y); 00075 tDelta.z = fabs(1.0/dir.z); 00076 } 00077 00078 00079 void next() 00080 { 00081 00082 if(tMax.x < tMax.y) 00083 { 00084 if(tMax.x < tMax.z) 00085 { 00086 ipos.x += step.x; 00087 tMax.x += tDelta.x; 00088 } 00089 else 00090 { 00091 ipos.z += step.z; 00092 tMax.z += tDelta.z; 00093 } 00094 } 00095 else 00096 { 00097 if(tMax.y < tMax.z) 00098 { 00099 ipos.y += step.y; 00100 tMax.y += tDelta.y; 00101 } 00102 else 00103 { 00104 ipos.z += step.z; 00105 tMax.z += tDelta.z; 00106 } 00107 } 00108 } 00109 00110 Vector3i getPos() { return ipos; } 00111 private: 00112 Vector3i ipos; 00113 Vector3i step; 00114 Vector3 tMax; 00115 Vector3 tDelta; 00116 }; 00117 00118 inline Vector3 disk2sphere(const Vector2& a) 00119 { 00120 float r = a.length(); 00121 Vector3 res; 00122 res.z = 1-r*2; 00123 float K = sqrt(2.0-r*r); 00124 res.x = a.x*K; 00125 res.y = a.y*K; 00126 return res; 00127 } 00128 00129 class PoissonSphere 00130 { 00131 public: 00132 PoissonSphere(int n, double limitDistance = -1.0) 00133 { 00134 next = 0; 00135 points.resize(n); 00136 00137 double limitDistSqr; 00138 if(limitDistance < 0.0) 00139 limitDistSqr = 2.2/n; 00140 else 00141 limitDistSqr = limitDistance*limitDistance; 00142 int i = 0; 00143 while(i < (int) points.size()) 00144 { 00145 00146 Vector3 candidate = randOnSphere(); 00147 bool bad = false; 00148 for(int j = 0; j < i; j++) 00149 { 00150 if((candidate-points[j]).lengthSqr() < limitDistSqr) 00151 { 00152 bad = true; 00153 break; 00154 } 00155 } 00156 if(!bad) points[i++] = candidate; 00157 } 00158 } 00159 00160 Vector3 getNext() { return points[next++ % points.size()]; } 00161 int getCount() { return points.size(); } 00162 private: 00163 std::vector<Vector3> points; 00164 int next; 00165 }; 00166 00167 inline bool intersectTriangleAABox(const Vector3& v1, const Vector3& v2, const Vector3& v3,const Vector3& bmin,const Vector3& bmax) 00168 { 00169 float triverts[3][3]; 00170 triverts[0][0] = v1.x; 00171 triverts[0][1] = v1.y; 00172 triverts[0][2] = v1.z; 00173 00174 triverts[1][0] = v2.x; 00175 triverts[1][1] = v2.y; 00176 triverts[1][2] = v2.z; 00177 00178 triverts[2][0] = v3.x; 00179 triverts[2][1] = v3.y; 00180 triverts[2][2] = v3.z; 00181 00182 Vector3 boxhfsize = (bmax-bmin)*0.5; 00183 Vector3 boxctr = (bmin+bmax)*0.5; 00184 00185 return triBoxOverlap((float*)&boxctr,(float*)&boxhfsize,triverts); 00186 } 00187 00188 inline void getBoundingBox(Vector3i& min, Vector3i& max, const Vector3i* arr, int n) 00189 { 00190 min.set(std::numeric_limits<int>::max()); 00191 max.set(std::numeric_limits<int>::min()); 00192 for(int i = 0; i < n; i++) 00193 { 00194 min.x = arr[i].x < min.x ? arr[i].x : min.x; 00195 min.y = arr[i].y < min.y ? arr[i].y : min.y; 00196 min.z = arr[i].z < min.z ? arr[i].z : min.z; 00197 max.x = arr[i].x > max.x ? arr[i].x : max.x; 00198 max.y = arr[i].y > max.y ? arr[i].y : max.y; 00199 max.z = arr[i].z > max.z ? arr[i].z : max.z; 00200 } 00201 } 00202 00203 #endif