00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef WAVEPACKET_GEOMETRY_3D_H__
00035 #define WAVEPACKET_GEOMETRY_3D_H__
00036
00037
00038 #include "common/common.h"
00039
00040 #include <math.h>
00041
00042
00043
00044
00045
00046
00047
00048 enum eContains {
00049 eContains_Fully = 0x01,
00050 eContains_Partial = 0x02,
00051 eContains_None = 0x10,
00052
00053
00054 eContains_HitMask = 0x03,
00055
00056
00057 eContains_Invalid = 0
00058 };
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 struct point3d_t {
00075
00076 point3d_t(void) throw() { }
00077 point3d_t(IN float ix, IN float iy, IN float iz) throw() :
00078 x(ix), y(iy), z(iz) { }
00079
00080
00081 void clear(void) throw() {
00082 x = y = z = 0.0;
00083 }
00084
00085 void set(IN float ix, IN float iy, IN float iz) throw() {
00086 x = ix; y = iy; z = iz;
00087 }
00088
00089 void dump(IN const char * title) const throw() {
00090 DPRINTF("%s (%f, %f, %f)", title, x, y, z);
00091 }
00092
00093 void increment(IN const point3d_t& p) throw() {
00094 x += p.x;
00095 y += p.y;
00096 z += p.z;
00097 }
00098
00099 void decrement(IN const point3d_t& p) throw() {
00100 x -= p.x;
00101 y -= p.y;
00102 z -= p.z;
00103 }
00104
00105 void scale(IN float r) throw() {
00106 x *= r;
00107 y *= r;
00108 z *= r;
00109 }
00110
00111 void operator *= (IN float r) throw() { this->scale(r); }
00112
00113 void operator += (IN const point3d_t& p) throw() {
00114 increment(p);
00115 }
00116
00117 void operator -= (IN const point3d_t& p) throw() {
00118 decrement(p);
00119 }
00120
00121 point3d_t operator - (void) const throw() {
00122 return point3d_t(-x, -y, -z);
00123 }
00124
00125
00126 float x;
00127 float y;
00128 float z;
00129 };
00130
00131
00132
00133 point3d_t operator * (IN const point3d_t& p, IN float r) throw();
00134 inline point3d_t operator * (IN float r, IN const point3d_t& p) throw() {
00135 return p * r;
00136 }
00137
00138 inline point3d_t operator + (IN const point3d_t& p, IN const point3d_t& q) throw()
00139 {
00140 return point3d_t(p.x + q.x, p.y + q.y, p.z + q.z);
00141 }
00142
00143 inline point3d_t operator - (IN const point3d_t& p, IN const point3d_t& q) throw()
00144 {
00145 return point3d_t(p.x - q.x, p.y - q.y, p.z - q.z);
00146 }
00147
00148
00149 inline float dotProduct(IN const point3d_t& p, IN const point3d_t& q) throw()
00150 {
00151 return (p.x * q.x) + (p.y * q.y) + (p.z * q.z);
00152 }
00153
00154
00155 inline point3d_t
00156 crossProduct(IN const point3d_t& p, IN const point3d_t& q) throw()
00157 {
00158 point3d_t r;
00159 r.x = p.y * q.z - p.z * q.y;
00160 r.y = p.z * q.x - p.x * q.z;
00161 r.z = p.x * q.y - p.y * q.x;
00162 return r;
00163 }
00164
00165
00166
00167 typedef point3d_t vector3d_t;
00168
00169
00170
00171
00172 struct rect3d_t {
00173
00174 enum eConstants {
00175 eMaxCorners = 8,
00176 eMaxEdges = 12
00177 };
00178
00179
00180 void clear(void) throw() {
00181 x0 = y0 = z0 = x1 = y1 = z1 = 0.0;
00182 }
00183
00184 void dump(IN const char * title) const throw() {
00185 DPRINTF("%s (%f, %f, %f) - (%f, %f, %f)",
00186 title, x0, y0, z0, x1, y1, z1);
00187 }
00188
00189 bool isValid(void) const throw() {
00190 return ((x1 >= x0) && (y1 >= y0) && (z1 >= z0));
00191 }
00192
00193 void validate(IN const char * msg = NULL) const throw() {
00194 if (!this->isValid()) {
00195 this->dump("Invalid!");
00196 ASSERT(false, "rect validation failed: %s", msg);
00197 }
00198 }
00199
00200 bool containsPoint(IN const point3d_t& p) const throw() {
00201 return (p.x >= x0 && p.x <= x1 &&
00202 p.y >= y0 && p.y <= y1 &&
00203 p.z >= z0 && p.z <= z1);
00204 }
00205
00206 bool intersectsRect(IN const rect3d_t& r) const throw() {
00207 if (r.x1 < x0 ||
00208 r.x0 > x1 ||
00209 r.y1 < y0 ||
00210 r.y0 > y1 ||
00211 r.z1 < z0 ||
00212 r.z0 > z1)
00213 return false;
00214 return true;
00215 }
00216
00217 bool containsRect(IN const rect3d_t& r) const throw() {
00218 return (r.x0 >= x0 &&
00219 r.x1 <= x1 &&
00220 r.y0 >= y0 &&
00221 r.y1 <= y1 &&
00222 r.z0 >= z0 &&
00223 r.z1 <= z1);
00224 }
00225
00226 void expand(IN const rect3d_t& r) throw() {
00227 this->validate();
00228 r.validate();
00229 if (r.x0 < x0)
00230 x0 = r.x0;
00231 if (r.y0 < y0)
00232 y0 = r.y0;
00233 if (r.z0 < z0)
00234 z0 = r.z0;
00235
00236 if (r.x1 > x1)
00237 x1 = r.x1;
00238 if (r.y1 > y1)
00239 y1 = r.y1;
00240 if (r.z1 > z1)
00241 z1 = r.z1;
00242 }
00243
00244 void inflate(IN float r) throw() {
00245 x0 -= r; x1 += r;
00246 y0 -= r; y1 += r;
00247 z0 -= r; z1 += r;
00248 }
00249
00250 void setToPoint(IN const point3d_t& p) throw() {
00251 x0 = x1 = p.x;
00252 y0 = y1 = p.y;
00253 z0 = z1 = p.z;
00254 }
00255
00256 void includePoint(IN const point3d_t& p) throw() {
00257 if (p.x < x0)
00258 x0 = p.x;
00259 if (p.x > x1)
00260 x1 = p.x;
00261 if (p.y < y0)
00262 y0 = p.y;
00263 if (p.y > y1)
00264 y1 = p.y;
00265 if (p.z < z0)
00266 z0 = p.z;
00267 if (p.z > z1)
00268 z1 = p.z;
00269 }
00270
00271 void getBoundingRectForSphere(IN const point3d_t& center,
00272 IN float radius) throw() {
00273 ASSERT(radius >= 0.0, "Bad radius: %f", radius);
00274 x0 = center.x - radius;
00275 x1 = center.x + radius;
00276 y0 = center.y - radius;
00277 y1 = center.y + radius;
00278 z0 = center.z - radius;
00279 z1 = center.z + radius;
00280 }
00281
00282 point3d_t getMidpoint(void) const throw() {
00283 return point3d_t(0.5 * (x0 + x1),
00284 0.5 * (y0 + y1),
00285 0.5 * (z0 + z1));
00286 }
00287
00288 float getDiagonal(void) const throw() {
00289 float dx = x1 - x0;
00290 float dy = y1 - y0;
00291 float dz = z1 - z0;
00292 float d2 = (dx * dx) + (dy * dy) + (dz * dz);
00293 return sqrt(d2);
00294 }
00295
00296
00297 void restrictPoint(IO point3d_t& p) const throw() {
00298
00299 if (p.x < x0)
00300 p.x = x0;
00301 if (p.x > x1)
00302 p.x = x1;
00303 if (p.y < y0)
00304 p.y = y0;
00305 if (p.y > y1)
00306 p.y = y1;
00307 if (p.z < z0)
00308 p.z = z0;
00309 if (p.z > z1)
00310 p.z = z1;
00311 }
00312
00313
00314 point3d_t getCorner(IN int index) const throw();
00315
00316
00317
00318 void getEdge(IN int index,
00319 OUT point3d_t& p0,
00320 OUT point3d_t& p1) const throw();
00321
00322 void translate(IN const point3d_t& delta) throw() {
00323 x0 += delta.x;
00324 x1 += delta.x;
00325 y0 += delta.y;
00326 y1 += delta.y;
00327 z0 += delta.z;
00328 z1 += delta.z;
00329 }
00330
00331
00332 float x0;
00333 float y0;
00334 float z0;
00335 float x1;
00336 float y1;
00337 float z1;
00338 };
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 const vector3d_t& normalize(IO vector3d_t& v) throw();
00349
00350 static inline float
00351 getDistance2
00352 (
00353 IN const point3d_t& p0,
00354 IN const point3d_t& p1
00355 )
00356 throw()
00357 {
00358 float dx = p0.x - p1.x;
00359 float dy = p0.y - p1.y;
00360 float dz = p0.z - p1.z;
00361
00362 return (dx * dx) + (dy * dy) + (dz * dz);
00363 }
00364
00365
00366 point3d_t readPoint(IN std::istream& stream);
00367 rect3d_t readRect(IN std::istream& stream);
00368
00369 void parsePoint3d(IO std::istream& stream, OUT point3d_t& p);
00370 void parseRect3d(IO std::istream& stream, OUT rect3d_t& r);
00371
00372 void parsePoint3d(IN const char * string, OUT point3d_t& p);
00373 void parseRect3d(IN const char * string, OUT rect3d_t& r);
00374
00375 #endif // WAVEPACKET_GEOMETRY_3D_H__
00376