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
00023 #include "cstypes.h"
00024 #include "vector2.h"
00025 #include "vector3.h"
00026 #include "segment.h"
00027
00028 class csPlane3;
00029
00034 #define CS_BOUNDINGBOX_MAXVALUE 1000000000.
00035
00037 #define BOX_CORNER_xy 0
00038 #define BOX_CORNER_xY 1
00039 #define BOX_CORNER_Xy 2
00040 #define BOX_CORNER_XY 3
00041
00046 #define BOX_EDGE_xy_Xy 0
00047 #define BOX_EDGE_Xy_xy 1
00048 #define BOX_EDGE_Xy_XY 2
00049 #define BOX_EDGE_XY_Xy 3
00050 #define BOX_EDGE_XY_xY 4
00051 #define BOX_EDGE_xY_XY 5
00052 #define BOX_EDGE_xY_xy 6
00053 #define BOX_EDGE_xy_xY 7
00054
00062 class csBox2
00063 {
00064 private:
00065 struct bEdge
00066 {
00067 uint8 v1, v2;
00068 };
00069
00070
00071 static bEdge edges[8];
00072
00073 protected:
00075 csVector2 minbox;
00077 csVector2 maxbox;
00078
00079 public:
00081 float MinX () const { return minbox.x; }
00083 float MinY () const { return minbox.y; }
00085 float MaxX () const { return maxbox.x; }
00087 float MaxY () const { return maxbox.y; }
00089 float Min (int idx) const { return idx ? minbox.y : minbox.x; }
00091 float Max (int idx) const { return idx ? maxbox.y : maxbox.x; }
00093 const csVector2& Min () const { return minbox; }
00095 const csVector2& Max () const { return maxbox; }
00096
00104 csVector2 GetCorner (int corner) const;
00105
00109 csVector2 GetCenter () const { return (minbox+maxbox)/2; }
00110
00115 void SetCenter (const csVector2& c);
00116
00120 void SetSize (const csVector2& s);
00121
00126 void GetEdgeInfo (int edge, int& v1, int& v2) const
00127 {
00128 v1 = edges[edge].v1;
00129 v2 = edges[edge].v2;
00130 }
00131
00136 csSegment2 GetEdge (int edge) const
00137 {
00138 return csSegment2 (GetCorner (edges[edge].v1), GetCorner (edges[edge].v2));
00139 }
00140
00145 void GetEdge (int edge, csSegment2& e) const
00146 {
00147 e.SetStart (GetCorner (edges[edge].v1));
00148 e.SetEnd (GetCorner (edges[edge].v2));
00149 }
00150
00157 static bool Intersect (float minx, float miny, float maxx, float maxy,
00158 csVector2* poly, int num_poly);
00159
00166 static bool Intersect (const csVector2& minbox, const csVector2& maxbox,
00167 csVector2* poly, int num_poly)
00168 {
00169 return Intersect (minbox.x, minbox.y, maxbox.x, maxbox.y, poly, num_poly);
00170 }
00171
00178 bool Intersect (csVector2* poly, int num_poly) const
00179 {
00180 return Intersect (minbox, maxbox, poly, num_poly);
00181 }
00182
00184 bool In (float x, float y) const
00185 {
00186 if (x < minbox.x || x > maxbox.x) return false;
00187 if (y < minbox.y || y > maxbox.y) return false;
00188 return true;
00189 }
00190
00192 bool In (const csVector2& v) const
00193 {
00194 return In (v.x, v.y);
00195 }
00196
00198 bool Overlap (const csBox2& box) const
00199 {
00200 if (maxbox.x < box.minbox.x || minbox.x > box.maxbox.x) return false;
00201 if (maxbox.y < box.minbox.y || minbox.y > box.maxbox.y) return false;
00202 return true;
00203 }
00204
00206 bool Contains (const csBox2& box) const
00207 {
00208 return (box.minbox.x >= minbox.x && box.maxbox.x <= maxbox.x) &&
00209 (box.minbox.y >= minbox.y && box.maxbox.y <= maxbox.y);
00210 }
00211
00213 bool Empty () const
00214 {
00215 if (minbox.x > maxbox.x) return true;
00216 if (minbox.y > maxbox.y) return true;
00217 return false;
00218 }
00219
00224 float SquaredOriginDist () const;
00225
00231 float SquaredOriginMaxDist () const;
00232
00234 void StartBoundingBox ()
00235 {
00236 minbox.x = CS_BOUNDINGBOX_MAXVALUE; minbox.y = CS_BOUNDINGBOX_MAXVALUE;
00237 maxbox.x = -CS_BOUNDINGBOX_MAXVALUE; maxbox.y = -CS_BOUNDINGBOX_MAXVALUE;
00238 }
00239
00241 void StartBoundingBox (const csVector2& v)
00242 {
00243 minbox = v;
00244 maxbox = v;
00245 }
00246
00248 void StartBoundingBox (float x, float y)
00249 {
00250 minbox.x = maxbox.x = x;
00251 minbox.y = maxbox.y = y;
00252 }
00253
00255 void AddBoundingVertex (float x, float y)
00256 {
00257 if (x < minbox.x) minbox.x = x; if (x > maxbox.x) maxbox.x = x;
00258 if (y < minbox.y) minbox.y = y; if (y > maxbox.y) maxbox.y = y;
00259 }
00260
00262 void AddBoundingVertex (const csVector2& v)
00263 {
00264 AddBoundingVertex (v.x, v.y);
00265 }
00266
00272 void AddBoundingVertexSmart (float x, float y)
00273 {
00274 if (x < minbox.x) minbox.x = x; else if (x > maxbox.x) maxbox.x = x;
00275 if (y < minbox.y) minbox.y = y; else if (y > maxbox.y) maxbox.y = y;
00276 }
00277
00283 void AddBoundingVertexSmart (const csVector2& v)
00284 {
00285 AddBoundingVertexSmart (v.x, v.y);
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00303 csBox2 () : minbox (CS_BOUNDINGBOX_MAXVALUE, CS_BOUNDINGBOX_MAXVALUE),
00304 maxbox (-CS_BOUNDINGBOX_MAXVALUE, -CS_BOUNDINGBOX_MAXVALUE) {}
00305
00307 csBox2 (const csVector2& v) : minbox (v.x, v.y), maxbox (v.x, v.y) {}
00308
00310 csBox2 (float x1, float y1, float x2, float y2) :
00311 minbox (x1, y1), maxbox (x2, y2)
00312 { if (Empty ()) StartBoundingBox (); }
00313
00315 void Set (const csVector2& bmin, const csVector2& bmax)
00316 {
00317 minbox = bmin;
00318 maxbox = bmax;
00319 }
00320
00322 void Set (float x1, float y1, float x2, float y2)
00323 {
00324 if (x1>x2 || y1>y2) StartBoundingBox();
00325 else { minbox.x = x1; minbox.y = y1; maxbox.x = x2; maxbox.y = y2; }
00326 }
00327
00329 csBox2& operator+= (const csBox2& box);
00331 csBox2& operator+= (const csVector2& point);
00333 csBox2& operator*= (const csBox2& box);
00334
00336 friend csBox2 operator+ (const csBox2& box1, const csBox2& box2);
00338 friend csBox2 operator+ (const csBox2& box, const csVector2& point);
00340 friend csBox2 operator* (const csBox2& box1, const csBox2& box2);
00341
00343 friend bool operator== (const csBox2& box1, const csBox2& box2);
00345 friend bool operator!= (const csBox2& box1, const csBox2& box2);
00347 friend bool operator< (const csBox2& box1, const csBox2& box2);
00349 friend bool operator> (const csBox2& box1, const csBox2& box2);
00351 friend bool operator< (const csVector2& point, const csBox2& box);
00352 };
00353
00358 #define BOX_CORNER_xyz 0
00359 #define BOX_CORNER_xyZ 1
00360 #define BOX_CORNER_xYz 2
00361 #define BOX_CORNER_xYZ 3
00362 #define BOX_CORNER_Xyz 4
00363 #define BOX_CORNER_XyZ 5
00364 #define BOX_CORNER_XYz 6
00365 #define BOX_CORNER_XYZ 7
00366
00371 #define BOX_SIDE_x 0
00372 #define BOX_SIDE_X 1
00373 #define BOX_SIDE_y 2
00374 #define BOX_SIDE_Y 3
00375 #define BOX_SIDE_z 4
00376 #define BOX_SIDE_Z 5
00377 #define BOX_INSIDE 6
00378
00383 #define BOX_EDGE_Xyz_xyz 0
00384 #define BOX_EDGE_xyz_Xyz 1
00385 #define BOX_EDGE_xyz_xYz 2
00386 #define BOX_EDGE_xYz_xyz 3
00387 #define BOX_EDGE_xYz_XYz 4
00388 #define BOX_EDGE_XYz_xYz 5
00389 #define BOX_EDGE_XYz_Xyz 6
00390 #define BOX_EDGE_Xyz_XYz 7
00391 #define BOX_EDGE_Xyz_XyZ 8
00392 #define BOX_EDGE_XyZ_Xyz 9
00393 #define BOX_EDGE_XyZ_XYZ 10
00394 #define BOX_EDGE_XYZ_XyZ 11
00395 #define BOX_EDGE_XYZ_XYz 12
00396 #define BOX_EDGE_XYz_XYZ 13
00397 #define BOX_EDGE_XYZ_xYZ 14
00398 #define BOX_EDGE_xYZ_XYZ 15
00399 #define BOX_EDGE_xYZ_xYz 16
00400 #define BOX_EDGE_xYz_xYZ 17
00401 #define BOX_EDGE_xYZ_xyZ 18
00402 #define BOX_EDGE_xyZ_xYZ 19
00403 #define BOX_EDGE_xyZ_xyz 20
00404 #define BOX_EDGE_xyz_xyZ 21
00405 #define BOX_EDGE_xyZ_XyZ 22
00406 #define BOX_EDGE_XyZ_xyZ 23
00407
00415 class csBox3
00416 {
00417 protected:
00419 csVector3 minbox;
00421 csVector3 maxbox;
00422
00423 struct bEdge
00424 {
00425 uint8 v1, v2;
00426 uint8 fl, fr;
00427 };
00428 typedef uint8 bFace[4];
00429
00430
00431 static bEdge edges[24];
00432
00433 static bFace faces[6];
00434 public:
00436 float MinX () const { return minbox.x; }
00438 float MinY () const { return minbox.y; }
00440 float MinZ () const { return minbox.z; }
00442 float MaxX () const { return maxbox.x; }
00444 float MaxY () const { return maxbox.y; }
00446 float MaxZ () const { return maxbox.z; }
00448 float Min (int idx) const
00449 { return idx == 1 ? minbox.y : idx == 0 ? minbox.x : minbox.z; }
00451 float Max (int idx) const
00452 { return idx == 1 ? maxbox.y : idx == 0 ? maxbox.x : maxbox.z; }
00454 const csVector3& Min () const { return minbox; }
00456 const csVector3& Max () const { return maxbox; }
00457
00466 csVector3 GetCorner (int corner) const;
00467
00472 void GetEdgeInfo (int edge, int& v1, int& v2, int& fleft, int& fright) const
00473 {
00474 v1 = edges[edge].v1;
00475 v2 = edges[edge].v2;
00476 fleft = edges[edge].fl;
00477 fright = edges[edge].fr;
00478 }
00479
00484 UByte* GetFaceEdges (int face) const
00485 {
00486 return faces[face];
00487 }
00488
00492 csVector3 GetCenter () const { return (minbox+maxbox)/2; }
00493
00498 void SetCenter (const csVector3& c);
00499
00503 void SetSize (const csVector3& s);
00504
00509 csBox2 GetSide (int side) const;
00510
00517 int GetVisibleSides (const csVector3& pos, int* visible_sides) const;
00518
00523 static int OtherSide (int side)
00524 {
00525 return side ^ 1;
00526 }
00527
00533 csSegment3 GetEdge (int edge) const
00534 {
00535 return csSegment3 (GetCorner (edges[edge].v1), GetCorner (edges[edge].v2));
00536 }
00537
00543 void GetEdge (int edge, csSegment3& e) const
00544 {
00545 e.SetStart (GetCorner (edges[edge].v1));
00546 e.SetEnd (GetCorner (edges[edge].v2));
00547 }
00548
00550 bool In (float x, float y, float z) const
00551 {
00552 if (x < minbox.x || x > maxbox.x) return false;
00553 if (y < minbox.y || y > maxbox.y) return false;
00554 if (z < minbox.z || z > maxbox.z) return false;
00555 return true;
00556 }
00557
00559 bool In (const csVector3& v) const
00560 {
00561 return In (v.x, v.y, v.z);
00562 }
00563
00565 bool Overlap (const csBox3& box) const
00566 {
00567 if (maxbox.x < box.minbox.x || minbox.x > box.maxbox.x) return false;
00568 if (maxbox.y < box.minbox.y || minbox.y > box.maxbox.y) return false;
00569 if (maxbox.z < box.minbox.z || minbox.z > box.maxbox.z) return false;
00570 return true;
00571 }
00572
00574 bool Contains (const csBox3& box) const
00575 {
00576 return (box.minbox.x >= minbox.x && box.maxbox.x <= maxbox.x) &&
00577 (box.minbox.y >= minbox.y && box.maxbox.y <= maxbox.y) &&
00578 (box.minbox.z >= minbox.z && box.maxbox.z <= maxbox.z);
00579 }
00580
00582 bool Empty () const
00583 {
00584 if (minbox.x > maxbox.x) return true;
00585 if (minbox.y > maxbox.y) return true;
00586 if (minbox.z > maxbox.z) return true;
00587 return false;
00588 }
00589
00591 void StartBoundingBox ()
00592 {
00593 minbox.x = CS_BOUNDINGBOX_MAXVALUE;
00594 minbox.y = CS_BOUNDINGBOX_MAXVALUE;
00595 minbox.z = CS_BOUNDINGBOX_MAXVALUE;
00596 maxbox.x = -CS_BOUNDINGBOX_MAXVALUE;
00597 maxbox.y = -CS_BOUNDINGBOX_MAXVALUE;
00598 maxbox.z = -CS_BOUNDINGBOX_MAXVALUE;
00599 }
00600
00602 void StartBoundingBox (const csVector3& v)
00603 {
00604 minbox = v; maxbox = v;
00605 }
00606
00608 void AddBoundingVertex (float x, float y, float z)
00609 {
00610 if (x < minbox.x) minbox.x = x; if (x > maxbox.x) maxbox.x = x;
00611 if (y < minbox.y) minbox.y = y; if (y > maxbox.y) maxbox.y = y;
00612 if (z < minbox.z) minbox.z = z; if (z > maxbox.z) maxbox.z = z;
00613 }
00614
00616 void AddBoundingVertex (const csVector3& v)
00617 {
00618 AddBoundingVertex (v.x, v.y, v.z);
00619 }
00620
00626 void AddBoundingVertexSmart (float x, float y, float z)
00627 {
00628 if (x < minbox.x) minbox.x = x; else if (x > maxbox.x) maxbox.x = x;
00629 if (y < minbox.y) minbox.y = y; else if (y > maxbox.y) maxbox.y = y;
00630 if (z < minbox.z) minbox.z = z; else if (z > maxbox.z) maxbox.z = z;
00631 }
00632
00638 void AddBoundingVertexSmart (const csVector3& v)
00639 {
00640 AddBoundingVertexSmart (v.x, v.y, v.z);
00641 }
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00658 csBox3 () :
00659 minbox ( CS_BOUNDINGBOX_MAXVALUE,
00660 CS_BOUNDINGBOX_MAXVALUE,
00661 CS_BOUNDINGBOX_MAXVALUE),
00662 maxbox (-CS_BOUNDINGBOX_MAXVALUE,
00663 -CS_BOUNDINGBOX_MAXVALUE,
00664 -CS_BOUNDINGBOX_MAXVALUE) {}
00665
00667 csBox3 (const csVector3& v) : minbox (v), maxbox (v) { }
00668
00670 csBox3 (const csVector3& v1, const csVector3& v2) :
00671 minbox (v1), maxbox (v2)
00672 { if (Empty ()) StartBoundingBox (); }
00673
00675 csBox3 (float x1, float y1, float z1, float x2, float y2, float z2) :
00676 minbox (x1, y1, z1), maxbox (x2, y2, z2)
00677 { if (Empty ()) StartBoundingBox (); }
00678
00680 void Set (const csVector3& bmin, const csVector3& bmax)
00681 {
00682 minbox = bmin;
00683 maxbox = bmax;
00684 }
00685
00687 void Set (float x1, float y1, float z1, float x2, float y2, float z2)
00688 {
00689 if (x1>x2 || y1>y2 || z1>z2) StartBoundingBox();
00690 else
00691 {
00692 minbox.x = x1; minbox.y = y1; minbox.z = z1;
00693 maxbox.x = x2; maxbox.y = y2; maxbox.z = z2;
00694 }
00695 }
00696
00700 bool AdjacentX (const csBox3& other) const;
00701
00705 bool AdjacentY (const csBox3& other) const;
00706
00710 bool AdjacentZ (const csBox3& other) const;
00711
00718 int Adjacent (const csBox3& other) const;
00719
00728 void GetConvexOutline (const csVector3& pos,
00729 csVector3* array, int& num_array, bool bVisible=false) const;
00730
00734 bool Between (const csBox3& box1, const csBox3& box2) const;
00735
00740 void ManhattanDistance (const csBox3& other, csVector3& dist) const;
00741
00746 float SquaredOriginDist () const;
00747
00753 float SquaredOriginMaxDist () const;
00754
00756 csBox3& operator+= (const csBox3& box);
00758 csBox3& operator+= (const csVector3& point);
00760 csBox3& operator*= (const csBox3& box);
00761
00763 friend csBox3 operator+ (const csBox3& box1, const csBox3& box2);
00765 friend csBox3 operator+ (const csBox3& box, const csVector3& point);
00767 friend csBox3 operator* (const csBox3& box1, const csBox3& box2);
00768
00770 friend bool operator== (const csBox3& box1, const csBox3& box2);
00772 friend bool operator!= (const csBox3& box1, const csBox3& box2);
00774 friend bool operator< (const csBox3& box1, const csBox3& box2);
00776 friend bool operator> (const csBox3& box1, const csBox3& box2);
00778 friend bool operator< (const csVector3& point, const csBox3& box);
00779 };
00780
00781 #endif // __CS_BOX_H__