00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __CS_BOX_H__
00021 #define __CS_BOX_H__
00022
00030 #include "cstypes.h"
00031 #include "vector2.h"
00032 #include "vector3.h"
00033 #include "segment.h"
00034
00035 class csPlane3;
00036 class csTransform;
00037
00042 #define CS_BOUNDINGBOX_MAXVALUE 1000000000.
00043
00047
00048 #define CS_BOX_CORNER_xy 0
00049
00050 #define CS_BOX_CORNER_xY 1
00051
00052 #define CS_BOX_CORNER_Xy 2
00053
00054 #define CS_BOX_CORNER_XY 3
00055
00061
00062 #define CS_BOX_EDGE_xy_Xy 0
00063
00064 #define CS_BOX_EDGE_Xy_xy 1
00065
00066 #define CS_BOX_EDGE_Xy_XY 2
00067
00068 #define CS_BOX_EDGE_XY_Xy 3
00069
00070 #define CS_BOX_EDGE_XY_xY 4
00071
00072 #define CS_BOX_EDGE_xY_XY 5
00073
00074 #define CS_BOX_EDGE_xY_xy 6
00075
00076 #define CS_BOX_EDGE_xy_xY 7
00077
00086 class csBox2
00087 {
00088 private:
00089 struct bEdge
00090 {
00091 uint8 v1, v2;
00092 };
00093
00094
00095 static bEdge edges[8];
00096
00097 protected:
00099 csVector2 minbox;
00101 csVector2 maxbox;
00102
00103 public:
00105 float MinX () const { return minbox.x; }
00107 float MinY () const { return minbox.y; }
00109 float MaxX () const { return maxbox.x; }
00111 float MaxY () const { return maxbox.y; }
00113 float Min (int idx) const { return idx ? minbox.y : minbox.x; }
00115 float Max (int idx) const { return idx ? maxbox.y : maxbox.x; }
00117 const csVector2& Min () const { return minbox; }
00119 const csVector2& Max () const { return maxbox; }
00120
00128 csVector2 GetCorner (int corner) const;
00129
00133 csVector2 GetCenter () const { return (minbox+maxbox)/2; }
00134
00139 void SetCenter (const csVector2& c);
00140
00144 void SetSize (const csVector2& s);
00145
00150 void GetEdgeInfo (int edge, int& v1, int& v2) const
00151 {
00152 v1 = edges[edge].v1;
00153 v2 = edges[edge].v2;
00154 }
00155
00160 csSegment2 GetEdge (int edge) const
00161 {
00162 return csSegment2 (GetCorner (edges[edge].v1), GetCorner (edges[edge].v2));
00163 }
00164
00169 void GetEdge (int edge, csSegment2& e) const
00170 {
00171 e.SetStart (GetCorner (edges[edge].v1));
00172 e.SetEnd (GetCorner (edges[edge].v2));
00173 }
00174
00181 static bool Intersect (float minx, float miny, float maxx, float maxy,
00182 csVector2* poly, int num_poly);
00183
00190 static bool Intersect (const csVector2& minbox, const csVector2& maxbox,
00191 csVector2* poly, int num_poly)
00192 {
00193 return Intersect (minbox.x, minbox.y, maxbox.x, maxbox.y, poly, num_poly);
00194 }
00195
00202 bool Intersect (csVector2* poly, int num_poly) const
00203 {
00204 return Intersect (minbox, maxbox, poly, num_poly);
00205 }
00206
00208 bool In (float x, float y) const
00209 {
00210 if (x < minbox.x || x > maxbox.x) return false;
00211 if (y < minbox.y || y > maxbox.y) return false;
00212 return true;
00213 }
00214
00216 bool In (const csVector2& v) const
00217 {
00218 return In (v.x, v.y);
00219 }
00220
00222 bool Overlap (const csBox2& box) const
00223 {
00224 if (maxbox.x < box.minbox.x || minbox.x > box.maxbox.x) return false;
00225 if (maxbox.y < box.minbox.y || minbox.y > box.maxbox.y) return false;
00226 return true;
00227 }
00228
00230 bool Contains (const csBox2& box) const
00231 {
00232 return (box.minbox.x >= minbox.x && box.maxbox.x <= maxbox.x) &&
00233 (box.minbox.y >= minbox.y && box.maxbox.y <= maxbox.y);
00234 }
00235
00237 bool Empty () const
00238 {
00239 if (minbox.x > maxbox.x) return true;
00240 if (minbox.y > maxbox.y) return true;
00241 return false;
00242 }
00243
00248 float SquaredOriginDist () const;
00249
00255 float SquaredOriginMaxDist () const;
00256
00258 void StartBoundingBox ()
00259 {
00260 minbox.x = CS_BOUNDINGBOX_MAXVALUE; minbox.y = CS_BOUNDINGBOX_MAXVALUE;
00261 maxbox.x = -CS_BOUNDINGBOX_MAXVALUE; maxbox.y = -CS_BOUNDINGBOX_MAXVALUE;
00262 }
00263
00265 void StartBoundingBox (const csVector2& v)
00266 {
00267 minbox = v;
00268 maxbox = v;
00269 }
00270
00272 void StartBoundingBox (float x, float y)
00273 {
00274 minbox.x = maxbox.x = x;
00275 minbox.y = maxbox.y = y;
00276 }
00277
00279 void AddBoundingVertex (float x, float y)
00280 {
00281 if (x < minbox.x) minbox.x = x; if (x > maxbox.x) maxbox.x = x;
00282 if (y < minbox.y) minbox.y = y; if (y > maxbox.y) maxbox.y = y;
00283 }
00284
00286 void AddBoundingVertex (const csVector2& v)
00287 {
00288 AddBoundingVertex (v.x, v.y);
00289 }
00290
00296 void AddBoundingVertexSmart (float x, float y)
00297 {
00298 if (x < minbox.x) minbox.x = x; else if (x > maxbox.x) maxbox.x = x;
00299 if (y < minbox.y) minbox.y = y; else if (y > maxbox.y) maxbox.y = y;
00300 }
00301
00307 void AddBoundingVertexSmart (const csVector2& v)
00308 {
00309 AddBoundingVertexSmart (v.x, v.y);
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00327 csBox2 () : minbox (CS_BOUNDINGBOX_MAXVALUE, CS_BOUNDINGBOX_MAXVALUE),
00328 maxbox (-CS_BOUNDINGBOX_MAXVALUE, -CS_BOUNDINGBOX_MAXVALUE) {}
00329
00331 csBox2 (const csVector2& v) : minbox (v.x, v.y), maxbox (v.x, v.y) {}
00332
00334 csBox2 (float x1, float y1, float x2, float y2) :
00335 minbox (x1, y1), maxbox (x2, y2)
00336 { if (Empty ()) StartBoundingBox (); }
00337
00339 void Set (const csVector2& bmin, const csVector2& bmax)
00340 {
00341 minbox = bmin;
00342 maxbox = bmax;
00343 }
00344
00346 void Set (float x1, float y1, float x2, float y2)
00347 {
00348 if (x1>x2 || y1>y2) StartBoundingBox();
00349 else { minbox.x = x1; minbox.y = y1; maxbox.x = x2; maxbox.y = y2; }
00350 }
00351
00353 void SetMin (int idx, float val)
00354 {
00355 if (idx == 1) minbox.y = val;
00356 else minbox.x = val;
00357 }
00358
00360 void SetMax (int idx, float val)
00361 {
00362 if (idx == 1) maxbox.y = val;
00363 else maxbox.x = val;
00364 }
00365
00367 csBox2& operator+= (const csBox2& box);
00369 csBox2& operator+= (const csVector2& point);
00371 csBox2& operator*= (const csBox2& box);
00373 bool TestIntersect (const csBox2& box) const;
00374
00376 friend csBox2 operator+ (const csBox2& box1, const csBox2& box2);
00378 friend csBox2 operator+ (const csBox2& box, const csVector2& point);
00380 friend csBox2 operator* (const csBox2& box1, const csBox2& box2);
00381
00383 friend bool operator== (const csBox2& box1, const csBox2& box2);
00385 friend bool operator!= (const csBox2& box1, const csBox2& box2);
00387 friend bool operator< (const csBox2& box1, const csBox2& box2);
00389 friend bool operator> (const csBox2& box1, const csBox2& box2);
00391 friend bool operator< (const csVector2& point, const csBox2& box);
00392 };
00393
00398
00399 #define CS_BOX_CORNER_xyz 0
00400
00401 #define CS_BOX_CORNER_xyZ 1
00402
00403 #define CS_BOX_CORNER_xYz 2
00404
00405 #define CS_BOX_CORNER_xYZ 3
00406
00407 #define CS_BOX_CORNER_Xyz 4
00408
00409 #define CS_BOX_CORNER_XyZ 5
00410
00411 #define CS_BOX_CORNER_XYz 6
00412
00413 #define CS_BOX_CORNER_XYZ 7
00414
00420
00421 #define CS_BOX_SIDE_x 0
00422
00423 #define CS_BOX_SIDE_X 1
00424
00425 #define CS_BOX_SIDE_y 2
00426
00427 #define CS_BOX_SIDE_Y 3
00428
00429 #define CS_BOX_SIDE_z 4
00430
00431 #define CS_BOX_SIDE_Z 5
00432
00433 #define CS_BOX_INSIDE 6
00434
00440
00441 #define CS_BOX_EDGE_Xyz_xyz 0
00442
00443 #define CS_BOX_EDGE_xyz_Xyz 1
00444
00445 #define CS_BOX_EDGE_xyz_xYz 2
00446
00447 #define CS_BOX_EDGE_xYz_xyz 3
00448
00449 #define CS_BOX_EDGE_xYz_XYz 4
00450
00451 #define CS_BOX_EDGE_XYz_xYz 5
00452
00453 #define CS_BOX_EDGE_XYz_Xyz 6
00454
00455 #define CS_BOX_EDGE_Xyz_XYz 7
00456
00457 #define CS_BOX_EDGE_Xyz_XyZ 8
00458
00459 #define CS_BOX_EDGE_XyZ_Xyz 9
00460
00461 #define CS_BOX_EDGE_XyZ_XYZ 10
00462
00463 #define CS_BOX_EDGE_XYZ_XyZ 11
00464
00465 #define CS_BOX_EDGE_XYZ_XYz 12
00466
00467 #define CS_BOX_EDGE_XYz_XYZ 13
00468
00469 #define CS_BOX_EDGE_XYZ_xYZ 14
00470
00471 #define CS_BOX_EDGE_xYZ_XYZ 15
00472
00473 #define CS_BOX_EDGE_xYZ_xYz 16
00474
00475 #define CS_BOX_EDGE_xYz_xYZ 17
00476
00477 #define CS_BOX_EDGE_xYZ_xyZ 18
00478
00479 #define CS_BOX_EDGE_xyZ_xYZ 19
00480
00481 #define CS_BOX_EDGE_xyZ_xyz 20
00482
00483 #define CS_BOX_EDGE_xyz_xyZ 21
00484
00485 #define CS_BOX_EDGE_xyZ_XyZ 22
00486
00487 #define CS_BOX_EDGE_XyZ_xyZ 23
00488
00497 class csBox3
00498 {
00499 protected:
00501 csVector3 minbox;
00503 csVector3 maxbox;
00505 struct bEdge
00506 {
00507 uint8 v1, v2;
00508 uint8 fl, fr;
00509 };
00511 typedef uint8 bFace[4];
00516 static bEdge edges[24];
00518 static bFace faces[6];
00519 public:
00521 float MinX () const { return minbox.x; }
00523 float MinY () const { return minbox.y; }
00525 float MinZ () const { return minbox.z; }
00527 float MaxX () const { return maxbox.x; }
00529 float MaxY () const { return maxbox.y; }
00531 float MaxZ () const { return maxbox.z; }
00533 float Min (int idx) const
00534 { return idx == 1 ? minbox.y : idx == 0 ? minbox.x : minbox.z; }
00536 float Max (int idx) const
00537 { return idx == 1 ? maxbox.y : idx == 0 ? maxbox.x : maxbox.z; }
00539 const csVector3& Min () const { return minbox; }
00541 const csVector3& Max () const { return maxbox; }
00542
00551 csVector3 GetCorner (int corner) const;
00552
00557 void GetEdgeInfo (int edge, int& v1, int& v2, int& fleft, int& fright) const
00558 {
00559 v1 = edges[edge].v1;
00560 v2 = edges[edge].v2;
00561 fleft = edges[edge].fl;
00562 fright = edges[edge].fr;
00563 }
00564
00569 uint8* GetFaceEdges (int face) const
00570 {
00571 return faces[face];
00572 }
00573
00577 csVector3 GetCenter () const { return (minbox+maxbox)/2; }
00578
00583 void SetCenter (const csVector3& c);
00584
00588 void SetSize (const csVector3& s);
00589
00594 csBox2 GetSide (int side) const;
00595
00602 int GetVisibleSides (const csVector3& pos, int* visible_sides) const;
00603
00608 static int OtherSide (int side)
00609 {
00610 return side ^ 1;
00611 }
00612
00618 csSegment3 GetEdge (int edge) const
00619 {
00620 return csSegment3 (GetCorner (edges[edge].v1), GetCorner (edges[edge].v2));
00621 }
00622
00628 void GetEdge (int edge, csSegment3& e) const
00629 {
00630 e.SetStart (GetCorner (edges[edge].v1));
00631 e.SetEnd (GetCorner (edges[edge].v2));
00632 }
00633
00635 bool In (float x, float y, float z) const
00636 {
00637 if (x < minbox.x || x > maxbox.x) return false;
00638 if (y < minbox.y || y > maxbox.y) return false;
00639 if (z < minbox.z || z > maxbox.z) return false;
00640 return true;
00641 }
00642
00644 bool In (const csVector3& v) const
00645 {
00646 return In (v.x, v.y, v.z);
00647 }
00648
00650 bool Overlap (const csBox3& box) const
00651 {
00652 if (maxbox.x < box.minbox.x || minbox.x > box.maxbox.x) return false;
00653 if (maxbox.y < box.minbox.y || minbox.y > box.maxbox.y) return false;
00654 if (maxbox.z < box.minbox.z || minbox.z > box.maxbox.z) return false;
00655 return true;
00656 }
00657
00659 bool Contains (const csBox3& box) const
00660 {
00661 return (box.minbox.x >= minbox.x && box.maxbox.x <= maxbox.x) &&
00662 (box.minbox.y >= minbox.y && box.maxbox.y <= maxbox.y) &&
00663 (box.minbox.z >= minbox.z && box.maxbox.z <= maxbox.z);
00664 }
00665
00667 bool Empty () const
00668 {
00669 if (minbox.x > maxbox.x) return true;
00670 if (minbox.y > maxbox.y) return true;
00671 if (minbox.z > maxbox.z) return true;
00672 return false;
00673 }
00674
00676 void StartBoundingBox ()
00677 {
00678 minbox.x = CS_BOUNDINGBOX_MAXVALUE;
00679 minbox.y = CS_BOUNDINGBOX_MAXVALUE;
00680 minbox.z = CS_BOUNDINGBOX_MAXVALUE;
00681 maxbox.x = -CS_BOUNDINGBOX_MAXVALUE;
00682 maxbox.y = -CS_BOUNDINGBOX_MAXVALUE;
00683 maxbox.z = -CS_BOUNDINGBOX_MAXVALUE;
00684 }
00685
00687 void StartBoundingBox (const csVector3& v)
00688 {
00689 minbox = v; maxbox = v;
00690 }
00691
00693 void AddBoundingVertex (float x, float y, float z)
00694 {
00695 if (x < minbox.x) minbox.x = x; if (x > maxbox.x) maxbox.x = x;
00696 if (y < minbox.y) minbox.y = y; if (y > maxbox.y) maxbox.y = y;
00697 if (z < minbox.z) minbox.z = z; if (z > maxbox.z) maxbox.z = z;
00698 }
00699
00701 void AddBoundingVertex (const csVector3& v)
00702 {
00703 AddBoundingVertex (v.x, v.y, v.z);
00704 }
00705
00711 void AddBoundingVertexSmart (float x, float y, float z)
00712 {
00713 if (x < minbox.x) minbox.x = x; else if (x > maxbox.x) maxbox.x = x;
00714 if (y < minbox.y) minbox.y = y; else if (y > maxbox.y) maxbox.y = y;
00715 if (z < minbox.z) minbox.z = z; else if (z > maxbox.z) maxbox.z = z;
00716 }
00717
00723 void AddBoundingVertexSmart (const csVector3& v)
00724 {
00725 AddBoundingVertexSmart (v.x, v.y, v.z);
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00743 csBox3 () :
00744 minbox ( CS_BOUNDINGBOX_MAXVALUE,
00745 CS_BOUNDINGBOX_MAXVALUE,
00746 CS_BOUNDINGBOX_MAXVALUE),
00747 maxbox (-CS_BOUNDINGBOX_MAXVALUE,
00748 -CS_BOUNDINGBOX_MAXVALUE,
00749 -CS_BOUNDINGBOX_MAXVALUE) {}
00750
00752 csBox3 (const csVector3& v) : minbox (v), maxbox (v) { }
00753
00755 csBox3 (const csVector3& v1, const csVector3& v2) :
00756 minbox (v1), maxbox (v2)
00757 { if (Empty ()) StartBoundingBox (); }
00758
00760 csBox3 (float x1, float y1, float z1, float x2, float y2, float z2) :
00761 minbox (x1, y1, z1), maxbox (x2, y2, z2)
00762 { if (Empty ()) StartBoundingBox (); }
00763
00765 void Set (const csVector3& bmin, const csVector3& bmax)
00766 {
00767 minbox = bmin;
00768 maxbox = bmax;
00769 }
00770
00772 void Set (float x1, float y1, float z1, float x2, float y2, float z2)
00773 {
00774 if (x1>x2 || y1>y2 || z1>z2) StartBoundingBox();
00775 else
00776 {
00777 minbox.x = x1; minbox.y = y1; minbox.z = z1;
00778 maxbox.x = x2; maxbox.y = y2; maxbox.z = z2;
00779 }
00780 }
00781
00783 void SetMin (int idx, float val)
00784 {
00785 if (idx == 1) minbox.y = val;
00786 else if (idx == 0) minbox.x = val;
00787 else minbox.z = val;
00788 }
00789
00791 void SetMax (int idx, float val)
00792 {
00793 if (idx == 1) maxbox.y = val;
00794 else if (idx == 0) maxbox.x = val;
00795 else maxbox.z = val;
00796 }
00797
00801 bool AdjacentX (const csBox3& other) const;
00802
00806 bool AdjacentY (const csBox3& other) const;
00807
00811 bool AdjacentZ (const csBox3& other) const;
00812
00819 int Adjacent (const csBox3& other) const;
00820
00827 int CalculatePointSegment (const csVector3& pos) const;
00828
00837 void GetConvexOutline (const csVector3& pos,
00838 csVector3* array, int& num_array, bool bVisible=false) const;
00839
00843 bool Between (const csBox3& box1, const csBox3& box2) const;
00844
00849 void ManhattanDistance (const csBox3& other, csVector3& dist) const;
00850
00855 float SquaredOriginDist () const;
00856
00862 float SquaredOriginMaxDist () const;
00863
00875 bool ProjectBox (const csTransform& trans, float fov, float sx, float sy,
00876 csBox2& sbox, float& min_z, float& max_z) const;
00877
00879 csBox3& operator+= (const csBox3& box);
00881 csBox3& operator+= (const csVector3& point);
00883 csBox3& operator*= (const csBox3& box);
00885 bool TestIntersect (const csBox3& box) const;
00886
00888 friend csBox3 operator+ (const csBox3& box1, const csBox3& box2);
00890 friend csBox3 operator+ (const csBox3& box, const csVector3& point);
00892 friend csBox3 operator* (const csBox3& box1, const csBox3& box2);
00893
00895 friend bool operator== (const csBox3& box1, const csBox3& box2);
00897 friend bool operator!= (const csBox3& box1, const csBox3& box2);
00899 friend bool operator< (const csBox3& box1, const csBox3& box2);
00901 friend bool operator> (const csBox3& box1, const csBox3& box2);
00903 friend bool operator< (const csVector3& point, const csBox3& box);
00904 };
00905
00908 #endif // __CS_BOX_H__