Crystal Space: csgeom/box.h Source File (Crystal Space Public API Reference)

| ## Public API Reference

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# csgeom/box.h

Go to the documentation of this file.

    00001 /*
    00002     Copyright (C) 1998-2002 by Jorrit Tyberghein
    00003     Largely rewritten by Ivan Avramovic <ivan@avramovic.com>
    00004
    00005     This library is free software; you can redistribute it and/or
    00006     modify it under the terms of the GNU Library General Public
    00007     License as published by the Free Software Foundation; either
    00008     version 2 of the License, or (at your option) any later version.
    00009
    00010     This library is distributed in the hope that it will be useful,
    00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013     Library General Public License for more details.
    00014
    00015     You should have received a copy of the GNU Library General Public
    00016     License along with this library; if not, write to the Free
    00017     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00018 */
    00019
    00020 #ifndef __CS_BOX_H__
    00021 #define __CS_BOX_H__
    00022
    00030 #include "csextern.h"
    00031 #include "cstypes.h"    // for bool
    00032
    00033 #include "csgeom/csrect.h"
    00034 #include "csgeom/math.h"
    00035 #include "csgeom/vector2.h"
    00036 #include "csgeom/vector3.h"
    00037 #include "csgeom/segment.h"
    00038
    00039 #include "csutil/array.h"
    00040
    00041 class csPoly2D;
    00042 class csString;
    00043 class csTransform;
    00044
    00049 #define CS_BOUNDINGBOX_MAXVALUE 1000000000.
    00050
    00054 enum
    00055 {
    00057   CS_BOX_CORNER_xy = 0,
    00059   CS_BOX_CORNER_xY = 1,
    00061   CS_BOX_CORNER_Xy = 2,
    00063   CS_BOX_CORNER_XY = 3,
    00065   CS_BOX_CENTER2 = 4
    00066 };
    00073 enum
    00074 {
    00076   CS_BOX_EDGE_xy_Xy = 0,
    00078   CS_BOX_EDGE_Xy_xy = 1,
    00080   CS_BOX_EDGE_Xy_XY = 2,
    00082   CS_BOX_EDGE_XY_Xy = 3,
    00084   CS_BOX_EDGE_XY_xY = 4,
    00086   CS_BOX_EDGE_xY_XY = 5,
    00088   CS_BOX_EDGE_xY_xy = 6,
    00090   CS_BOX_EDGE_xy_xY = 7
    00091 };
    00101 class CS_CRYSTALSPACE_EXPORT csBox2
    00102 {
    00103 private:
    00104   struct bEdge
    00105   {
    00106     uint8 v1, v2; // Indices of vertex in bounding box (CS_BOX_CORNER_...)
    00107   };
    00108   // Index by edge number. Edge e and e+1 with e even are opposite edges.
    00109   // (CS_BOX_EDGE_...)
    00110   static const bEdge edges[8];
    00111
    00112 protected:
    00114   csVector2 minbox;
    00116   csVector2 maxbox;
    00117
    00118 public:
    00120   inline float MinX () const { return minbox.x; }
    00122   inline float MinY () const { return minbox.y; }
    00124   inline float MaxX () const { return maxbox.x; }
    00126   inline float MaxY () const { return maxbox.y; }
    00128   inline float Min (int idx) const { return idx ? minbox.y : minbox.x; }
    00130   inline float Max (int idx) const { return idx ? maxbox.y : maxbox.x; }
    00132   inline const csVector2& Min () const { return minbox; }
    00134   inline const csVector2& Max () const { return maxbox; }
    00136   inline float Area () const { return (MaxX()-MinX())*(MaxY()-MinY()); }
    00137
    00146   csVector2 GetCorner (int corner) const;
    00147
    00151   inline csVector2 GetCenter () const { return (minbox+maxbox)/2; }
    00152
    00157   void SetCenter (const csVector2& c);
    00158
    00162   void SetSize (const csVector2& s);
    00163
    00168   inline void GetEdgeInfo (int edge, int& v1, int& v2) const
    00169   {
    00170     v1 = edges[edge].v1;
    00171     v2 = edges[edge].v2;
    00172   }
    00173
    00178   inline csSegment2 GetEdge (int edge) const
    00179   {
    00180     return csSegment2 (GetCorner (edges[edge].v1), GetCorner (edges[edge].v2));
    00181   }
    00182
    00187   inline void GetEdge (int edge, csSegment2& e) const
    00188   {
    00189     e.SetStart (GetCorner (edges[edge].v1));
    00190     e.SetEnd (GetCorner (edges[edge].v2));
    00191   }
    00192
    00199   static bool Intersect (float minx, float miny, float maxx, float maxy,
    00200     csVector2* poly, int num_poly);
    00201
    00208   static inline bool Intersect (const csVector2& minbox, const csVector2& maxbox,
    00209     csVector2* poly, int num_poly)
    00210   {
    00211     return Intersect (minbox.x, minbox.y, maxbox.x, maxbox.y, poly, num_poly);
    00212   }
    00213
    00220   inline bool Intersect (csVector2* poly, int num_poly) const
    00221   {
    00222     return Intersect (minbox, maxbox, poly, num_poly);
    00223   }
    00224
    00226   inline bool In (float x, float y) const
    00227   {
    00228     if (x < minbox.x || x > maxbox.x) return false;
    00229     if (y < minbox.y || y > maxbox.y) return false;
    00230     return true;
    00231   }
    00232
    00234   inline bool In (const csVector2& v) const
    00235   {
    00236     return In (v.x, v.y);
    00237   }
    00238
    00240   inline bool Overlap (const csBox2& box) const
    00241   {
    00242     if (maxbox.x < box.minbox.x || minbox.x > box.maxbox.x) return false;
    00243     if (maxbox.y < box.minbox.y || minbox.y > box.maxbox.y) return false;
    00244     return true;
    00245   }
    00246
    00248   inline bool Contains (const csBox2& box) const
    00249   {
    00250     return (box.minbox.x >= minbox.x && box.maxbox.x <= maxbox.x) &&
    00251            (box.minbox.y >= minbox.y && box.maxbox.y <= maxbox.y);
    00252   }
    00253
    00255   inline bool Empty () const
    00256   {
    00257     if (minbox.x > maxbox.x) return true;
    00258     if (minbox.y > maxbox.y) return true;
    00259     return false;
    00260   }
    00261
    00266   float SquaredOriginDist () const;
    00267
    00273   float SquaredOriginMaxDist () const;
    00274
    00279   float SquaredPosDist (const csVector2& pos) const;
    00280
    00286   float SquaredPosMaxDist (const csVector2& pos) const;
    00287
    00289   inline void StartBoundingBox ()
    00290   {
    00291     minbox.x =  CS_BOUNDINGBOX_MAXVALUE;  minbox.y =  CS_BOUNDINGBOX_MAXVALUE;
    00292     maxbox.x = -CS_BOUNDINGBOX_MAXVALUE;  maxbox.y = -CS_BOUNDINGBOX_MAXVALUE;
    00293   }
    00294
    00296   inline void StartBoundingBox (const csVector2& v)
    00297   {
    00298     minbox = v;
    00299     maxbox = v;
    00300   }
    00301
    00303   inline void StartBoundingBox (float x, float y)
    00304   {
    00305     minbox.x = maxbox.x = x;
    00306     minbox.y = maxbox.y = y;
    00307   }
    00308
    00310   inline void AddBoundingVertex (float x, float y)
    00311   {
    00312     if (x < minbox.x) minbox.x = x;  if (x > maxbox.x) maxbox.x = x;
    00313     if (y < minbox.y) minbox.y = y;  if (y > maxbox.y) maxbox.y = y;
    00314   }
    00315
    00317   inline void AddBoundingVertex (const csVector2& v)
    00318   {
    00319     AddBoundingVertex (v.x, v.y);
    00320   }
    00321
    00327   inline void AddBoundingVertexSmart (float x, float y)
    00328   {
    00329     if (x < minbox.x) minbox.x = x; else if (x > maxbox.x) maxbox.x = x;
    00330     if (y < minbox.y) minbox.y = y; else if (y > maxbox.y) maxbox.y = y;
    00331   }
    00332
    00338   inline void AddBoundingVertexSmart (const csVector2& v)
    00339   {
    00340     AddBoundingVertexSmart (v.x, v.y);
    00341   }
    00342
    00347   inline bool AddBoundingVertexTest (float x, float y)
    00348   {
    00349     bool rc = false;
    00350     if (x < minbox.x) { minbox.x = x; rc = true; }
    00351     if (x > maxbox.x) { maxbox.x = x; rc = true; }
    00352     if (y < minbox.y) { minbox.y = y; rc = true; }
    00353     if (y > maxbox.y) { maxbox.y = y; rc = true; }
    00354     return rc;
    00355   }
    00356
    00361   inline bool AddBoundingVertexTest (const csVector2& v)
    00362   {
    00363     return AddBoundingVertexTest (v.x, v.y);
    00364   }
    00365
    00372   inline bool AddBoundingVertexSmartTest (float x, float y)
    00373   {
    00374     bool rc = false;
    00375     if (x < minbox.x) { minbox.x = x; rc = true; }
    00376     else if (x > maxbox.x) { maxbox.x = x; rc = true; }
    00377     if (y < minbox.y) { minbox.y = y; rc = true; }
    00378     else if (y > maxbox.y) { maxbox.y = y; rc = true; }
    00379     return rc;
    00380   }
    00381
    00388   inline bool AddBoundingVertexSmartTest (const csVector2& v)
    00389   {
    00390     return AddBoundingVertexSmartTest (v.x, v.y);
    00391   }
    00392
    00394   csBox2 () : minbox (CS_BOUNDINGBOX_MAXVALUE, CS_BOUNDINGBOX_MAXVALUE),
    00395              maxbox (-CS_BOUNDINGBOX_MAXVALUE, -CS_BOUNDINGBOX_MAXVALUE)
    00396   {}
    00397
    00399   csBox2 (const csVector2& v) : minbox (v.x, v.y), maxbox (v.x, v.y)
    00400   {}
    00401
    00403   csBox2 (float x1, float y1, float x2, float y2) :
    00404     minbox (x1, y1), maxbox (x2, y2)
    00405   { if (Empty ()) StartBoundingBox (); }
    00406
    00408   csBox2 (const csRect& r) : minbox (r.xmin, r.ymin), maxbox (r.xmax, r.ymax)
    00409   { }
    00410
    00412   inline void Set (const csVector2& bmin, const csVector2& bmax)
    00413   {
    00414     minbox = bmin;
    00415     maxbox = bmax;
    00416   }
    00417
    00419   inline void Set (float x1, float y1, float x2, float y2)
    00420   {
    00421     if (x1>x2 || y1>y2) StartBoundingBox();
    00422     else { minbox.x = x1;  minbox.y = y1;  maxbox.x = x2;  maxbox.y = y2; }
    00423   }
    00424
    00426   inline void SetMin (int idx, float val)
    00427   {
    00428     if (idx == 1) minbox.y = val;
    00429     else minbox.x = val;
    00430   }
    00431
    00433   inline void SetMax (int idx, float val)
    00434   {
    00435     if (idx == 1) maxbox.y = val;
    00436     else maxbox.x = val;
    00437   }
    00438
    00443   csString Description() const;
    00444
    00446   csBox2& operator+= (const csBox2& box);
    00448   csBox2& operator+= (const csVector2& point);
    00450   csBox2& operator*= (const csBox2& box);
    00452   bool TestIntersect (const csBox2& box) const;
    00453
    00455   friend CS_CRYSTALSPACE_EXPORT csBox2 operator+ (const csBox2& box1,
    00456     const csBox2& box2);
    00458   friend CS_CRYSTALSPACE_EXPORT csBox2 operator+ (const csBox2& box,
    00459     const csVector2& point);
    00461   friend CS_CRYSTALSPACE_EXPORT csBox2 operator* (const csBox2& box1,
    00462     const csBox2& box2);
    00463
    00465   friend CS_CRYSTALSPACE_EXPORT bool operator== (const csBox2& box1,
    00466     const csBox2& box2);
    00468   friend CS_CRYSTALSPACE_EXPORT bool operator!= (const csBox2& box1,
    00469     const csBox2& box2);
    00471   friend CS_CRYSTALSPACE_EXPORT bool operator< (const csBox2& box1,
    00472     const csBox2& box2);
    00474   friend CS_CRYSTALSPACE_EXPORT bool operator> (const csBox2& box1,
    00475     const csBox2& box2);
    00477   friend CS_CRYSTALSPACE_EXPORT bool operator< (const csVector2& point,
    00478     const csBox2& box);
    00479 };
    00480
    00485 enum
    00486 {
    00488   CS_BOX_CORNER_xyz = 0,
    00490   CS_BOX_CORNER_xyZ = 1,
    00492   CS_BOX_CORNER_xYz = 2,
    00494   CS_BOX_CORNER_xYZ = 3,
    00496   CS_BOX_CORNER_Xyz = 4,
    00498   CS_BOX_CORNER_XyZ = 5,
    00500   CS_BOX_CORNER_XYz = 6,
    00502   CS_BOX_CORNER_XYZ = 7,
    00504   CS_BOX_CENTER3 = 8
    00505 };
    00512 enum
    00513 {
    00515   CS_BOX_SIDE_x = 0,
    00517   CS_BOX_SIDE_X = 1,
    00519   CS_BOX_SIDE_y = 2,
    00521   CS_BOX_SIDE_Y = 3,
    00523   CS_BOX_SIDE_z = 4,
    00525   CS_BOX_SIDE_Z = 5,
    00527   CS_BOX_INSIDE = 6
    00528 };
    00535 enum
    00536 {
    00538   CS_BOX_EDGE_Xyz_xyz = 0,
    00540   CS_BOX_EDGE_xyz_Xyz = 1,
    00542   CS_BOX_EDGE_xyz_xYz = 2,
    00544   CS_BOX_EDGE_xYz_xyz = 3,
    00546   CS_BOX_EDGE_xYz_XYz = 4,
    00548   CS_BOX_EDGE_XYz_xYz = 5,
    00550   CS_BOX_EDGE_XYz_Xyz = 6,
    00552   CS_BOX_EDGE_Xyz_XYz = 7,
    00554   CS_BOX_EDGE_Xyz_XyZ = 8,
    00556   CS_BOX_EDGE_XyZ_Xyz = 9,
    00558   CS_BOX_EDGE_XyZ_XYZ = 10,
    00560   CS_BOX_EDGE_XYZ_XyZ = 11,
    00562   CS_BOX_EDGE_XYZ_XYz = 12,
    00564   CS_BOX_EDGE_XYz_XYZ = 13,
    00566   CS_BOX_EDGE_XYZ_xYZ = 14,
    00568   CS_BOX_EDGE_xYZ_XYZ = 15,
    00570   CS_BOX_EDGE_xYZ_xYz = 16,
    00572   CS_BOX_EDGE_xYz_xYZ = 17,
    00574   CS_BOX_EDGE_xYZ_xyZ = 18,
    00576   CS_BOX_EDGE_xyZ_xYZ = 19,
    00578   CS_BOX_EDGE_xyZ_xyz = 20,
    00580   CS_BOX_EDGE_xyz_xyZ = 21,
    00582   CS_BOX_EDGE_xyZ_XyZ = 22,
    00584   CS_BOX_EDGE_XyZ_xyZ = 23
    00585 };
    00595 class CS_CRYSTALSPACE_EXPORT csBox3
    00596 {
    00597 protected:
    00599   csVector3 minbox;
    00601   csVector3 maxbox;
    00605   struct bEdge
    00606   {
    00607     uint8 v1, v2; // Indices of vertex in bounding box (CS_BOX_CORNER_...)
    00608     uint8 fl, fr; // Indices of left/right faces sharing edge (CS_BOX_SIDE_...)
    00609   };
    00611   typedef uint8 bFace[4];
    00616   static const bEdge edges[24];
    00618   static const bFace faces[6];
    00620   struct Outline
    00621   {
    00622     int num;
    00623     int vertices[8];
    00624     int num_sides;
    00625     int sides[3];
    00626   };
    00628   static const Outline outlines[27];
    00629 public:
    00631   inline float MinX () const { return minbox.x; }
    00633   inline float MinY () const { return minbox.y; }
    00635   inline float MinZ () const { return minbox.z; }
    00637   inline float MaxX () const { return maxbox.x; }
    00639   inline float MaxY () const { return maxbox.y; }
    00641   inline float MaxZ () const { return maxbox.z; }
    00643   inline float Min (int idx) const
    00644   { return minbox[idx]; }
    00646   inline float Max (int idx) const
    00647   { return maxbox[idx]; }
    00649   inline const csVector3& Min () const { return minbox; }
    00651   inline const csVector3& Max () const { return maxbox; }
    00653   inline float Volume () const
    00654   { return (MaxX()-MinX())*(MaxY()-MinY())*(MaxZ()-MinZ()); }
    00656   inline float Area () const
    00657   {
    00658     float x = MaxX()-MinX();
    00659     float y = MaxY()-MinY();
    00660     float z = MaxZ()-MinZ();
    00661     return 2.0f*(x*y + x*z + y*z);
    00662   }
    00663
    00673   csVector3 GetCorner (int corner) const;
    00674
    00680   inline void GetEdgeInfo (int edge, int& v1, int& v2, int& fleft, int& fright) const
    00681   {
    00682     v1 = edges[edge].v1;
    00683     v2 = edges[edge].v2;
    00684     fleft = edges[edge].fl;
    00685     fright = edges[edge].fr;
    00686   }
    00687
    00692   inline const uint8* GetFaceEdges (int face) const
    00693   {
    00694     return faces[face];
    00695   }
    00696
    00700   inline csVector3 GetCenter () const { return (minbox+maxbox)/2; }
    00701
    00706   void SetCenter (const csVector3& c);
    00707
    00711   void SetSize (const csVector3& s);
    00712
    00716   inline csVector3 GetSize () const { return (maxbox-minbox); }
    00717
    00722   csBox2 GetSide (int side) const;
    00723
    00729   void GetAxisPlane (int side, int& axis, float& where) const;
    00730
    00737   int GetVisibleSides (const csVector3& pos, int* visible_sides) const;
    00738
    00743   static inline int OtherSide (int side)
    00744   {
    00745     return side ^ 1;
    00746   }
    00747
    00753   inline csSegment3 GetEdge (int edge) const
    00754   {
    00755     return csSegment3 (GetCorner (edges[edge].v1), GetCorner (edges[edge].v2));
    00756   }
    00757
    00763   inline void GetEdge (int edge, csSegment3& e) const
    00764   {
    00765     e.SetStart (GetCorner (edges[edge].v1));
    00766     e.SetEnd (GetCorner (edges[edge].v2));
    00767   }
    00768
    00770   inline bool In (float x, float y, float z) const
    00771   {
    00772     if (x < minbox.x || x > maxbox.x) return false;
    00773     if (y < minbox.y || y > maxbox.y) return false;
    00774     if (z < minbox.z || z > maxbox.z) return false;
    00775     return true;
    00776   }
    00777
    00779   inline bool In (const csVector3& v) const
    00780   {
    00781     return In (v.x, v.y, v.z);
    00782   }
    00783
    00785   inline bool Overlap (const csBox3& box) const
    00786   {
    00787     if (maxbox.x < box.minbox.x || minbox.x > box.maxbox.x) return false;
    00788     if (maxbox.y < box.minbox.y || minbox.y > box.maxbox.y) return false;
    00789     if (maxbox.z < box.minbox.z || minbox.z > box.maxbox.z) return false;
    00790     return true;
    00791   }
    00792
    00794   inline bool Contains (const csBox3& box) const
    00795   {
    00796     return (box.minbox.x >= minbox.x && box.maxbox.x <= maxbox.x) &&
    00797            (box.minbox.y >= minbox.y && box.maxbox.y <= maxbox.y) &&
    00798            (box.minbox.z >= minbox.z && box.maxbox.z <= maxbox.z);
    00799   }
    00800
    00802   inline bool Empty () const
    00803   {
    00804     if (minbox.x > maxbox.x) return true;
    00805     if (minbox.y > maxbox.y) return true;
    00806     if (minbox.z > maxbox.z) return true;
    00807     return false;
    00808   }
    00809
    00811   inline void StartBoundingBox ()
    00812   {
    00813     minbox.x =  CS_BOUNDINGBOX_MAXVALUE;
    00814     minbox.y =  CS_BOUNDINGBOX_MAXVALUE;
    00815     minbox.z =  CS_BOUNDINGBOX_MAXVALUE;
    00816     maxbox.x = -CS_BOUNDINGBOX_MAXVALUE;
    00817     maxbox.y = -CS_BOUNDINGBOX_MAXVALUE;
    00818     maxbox.z = -CS_BOUNDINGBOX_MAXVALUE;
    00819   }
    00820
    00822   inline void StartBoundingBox (const csVector3& v)
    00823   {
    00824     minbox = v; maxbox = v;
    00825   }
    00826
    00828   inline void AddBoundingVertex (float x, float y, float z)
    00829   {
    00830     if (x < minbox.x) minbox.x = x; if (x > maxbox.x) maxbox.x = x;
    00831     if (y < minbox.y) minbox.y = y; if (y > maxbox.y) maxbox.y = y;
    00832     if (z < minbox.z) minbox.z = z; if (z > maxbox.z) maxbox.z = z;
    00833   }
    00834
    00836   inline void AddBoundingVertex (const csVector3& v)
    00837   {
    00838     AddBoundingVertex (v.x, v.y, v.z);
    00839   }
    00840
    00846   inline void AddBoundingVertexSmart (float x, float y, float z)
    00847   {
    00848     if (x < minbox.x) minbox.x = x; else if (x > maxbox.x) maxbox.x = x;
    00849     if (y < minbox.y) minbox.y = y; else if (y > maxbox.y) maxbox.y = y;
    00850     if (z < minbox.z) minbox.z = z; else if (z > maxbox.z) maxbox.z = z;
    00851   }
    00852
    00858   inline void AddBoundingVertexSmart (const csVector3& v)
    00859   {
    00860     AddBoundingVertexSmart (v.x, v.y, v.z);
    00861   }
    00862
    00867   inline bool AddBoundingVertexTest (float x, float y, float z)
    00868   {
    00869     bool rc = false;
    00870     if (x < minbox.x) { minbox.x = x; rc = true; }
    00871     if (x > maxbox.x) { maxbox.x = x; rc = true; }
    00872     if (y < minbox.y) { minbox.y = y; rc = true; }
    00873     if (y > maxbox.y) { maxbox.y = y; rc = true; }
    00874     if (z < minbox.z) { minbox.z = z; rc = true; }
    00875     if (z > maxbox.z) { maxbox.z = z; rc = true; }
    00876     return rc;
    00877   }
    00878
    00883   inline bool AddBoundingVertexTest (const csVector3& v)
    00884   {
    00885     return AddBoundingVertexTest (v.x, v.y, v.z);
    00886   }
    00887
    00894   inline bool AddBoundingVertexSmartTest (float x, float y, float z)
    00895   {
    00896     bool rc = false;
    00897     if (x < minbox.x) { minbox.x = x; rc = true; }
    00898     else if (x > maxbox.x) { maxbox.x = x; rc = true; }
    00899     if (y < minbox.y) { minbox.y = y; rc = true; }
    00900     else if (y > maxbox.y) { maxbox.y = y; rc = true; }
    00901     if (z < minbox.z) { minbox.z = z; rc = true; }
    00902     else if (z > maxbox.z) { maxbox.z = z; rc = true; }
    00903     return rc;
    00904   }
    00905
    00912   inline bool AddBoundingVertexSmartTest (const csVector3& v)
    00913   {
    00914     return AddBoundingVertexSmartTest (v.x, v.y, v.z);
    00915   }
    00916
    00920   inline void AddBoundingBox (const csBox3& box)
    00921   {
    00922     minbox.x = csMin(minbox.x, box.minbox.x);
    00923     minbox.y = csMin(minbox.y, box.minbox.y);
    00924     minbox.z = csMin(minbox.z, box.minbox.z);
    00925
    00926     maxbox.x = csMax(maxbox.x, box.maxbox.x);
    00927     maxbox.y = csMax(maxbox.y, box.maxbox.y);
    00928     maxbox.z = csMax(maxbox.z, box.maxbox.z);
    00929   }
    00930
    00932   csBox3 () :
    00933     minbox ( CS_BOUNDINGBOX_MAXVALUE,
    00934              CS_BOUNDINGBOX_MAXVALUE,
    00935              CS_BOUNDINGBOX_MAXVALUE),
    00936     maxbox (-CS_BOUNDINGBOX_MAXVALUE,
    00937             -CS_BOUNDINGBOX_MAXVALUE,
    00938             -CS_BOUNDINGBOX_MAXVALUE) {}
    00939
    00941   csBox3 (const csVector3& v) : minbox (v), maxbox (v)
    00942   { }
    00943
    00945   csBox3 (const csVector3& v1, const csVector3& v2) :
    00946         minbox (v1), maxbox (v2)
    00947   { if (Empty ()) StartBoundingBox (); }
    00948
    00950   csBox3 (float x1, float y1, float z1, float x2, float y2, float z2) :
    00951     minbox (x1, y1, z1), maxbox (x2, y2, z2)
    00952   { if (Empty ()) StartBoundingBox (); }
    00953
    00955   inline void Set (const csVector3& bmin, const csVector3& bmax)
    00956   {
    00957     minbox = bmin;
    00958     maxbox = bmax;
    00959   }
    00960
    00962   inline void Set (float x1, float y1, float z1, float x2, float y2, float z2)
    00963   {
    00964     if (x1>x2 || y1>y2 || z1>z2) StartBoundingBox();
    00965     else
    00966     {
    00967       minbox.x = x1; minbox.y = y1; minbox.z = z1;
    00968       maxbox.x = x2; maxbox.y = y2; maxbox.z = z2;
    00969     }
    00970   }
    00971
    00973   inline void SetMin (int idx, float val)
    00974   {
    00975     if (idx == 1) minbox.y = val;
    00976     else if (idx == 0) minbox.x = val;
    00977     else minbox.z = val;
    00978   }
    00979
    00981   inline void SetMax (int idx, float val)
    00982   {
    00983     if (idx == 1) maxbox.y = val;
    00984     else if (idx == 0) maxbox.x = val;
    00985     else maxbox.z = val;
    00986   }
    00987
    00992   csString Description() const;
    00993
    00997   inline void Split (int axis, float where, csBox3& bl, csBox3& br) const
    00998   {
    00999     switch (axis)
    01000     {
    01001       case CS_AXIS_X:
    01002         bl.Set (minbox.x, minbox.y, minbox.z,
    01003                 where,    maxbox.y, maxbox.z);
    01004         br.Set (where,    minbox.y, minbox.z,
    01005                 maxbox.x, maxbox.y, maxbox.z);
    01006         break;
    01007       case CS_AXIS_Y:
    01008         bl.Set (minbox.x, minbox.y, minbox.z,
    01009                 maxbox.x, where,    maxbox.z);
    01010         br.Set (minbox.x, where,    minbox.z,
    01011                 maxbox.x, maxbox.y, maxbox.z);
    01012         break;
    01013       case CS_AXIS_Z:
    01014         bl.Set (minbox.x, minbox.y, minbox.z,
    01015                 maxbox.x, maxbox.y, where);
    01016         br.Set (minbox.x, minbox.y, where,
    01017                 maxbox.x, maxbox.y, maxbox.z);
    01018         break;
    01019     }
    01020   }
    01021
    01028   inline int TestSplit (int axis, float where) const
    01029   {
    01030     if (maxbox[axis] < where) return -1;
    01031     if (minbox[axis] > where) return 1;
    01032     return 0;
    01033   }
    01034
    01038   bool AdjacentX (const csBox3& other, float epsilon = SMALL_EPSILON) const;
    01039
    01043   bool AdjacentY (const csBox3& other, float epsilon = SMALL_EPSILON) const;
    01044
    01048   bool AdjacentZ (const csBox3& other, float epsilon = SMALL_EPSILON) const;
    01049
    01057   int Adjacent (const csBox3& other, float epsilon = SMALL_EPSILON) const;
    01058
    01065   int CalculatePointSegment (const csVector3& pos) const;
    01066
    01075   void GetConvexOutline (const csVector3& pos,
    01076         csVector3* array, int& num_array, bool bVisible=false) const;
    01077
    01081   bool Between (const csBox3& box1, const csBox3& box2) const;
    01082
    01087   void ManhattanDistance (const csBox3& other, csVector3& dist) const;
    01088
    01093   float SquaredOriginDist () const;
    01094
    01100   float SquaredOriginMaxDist () const;
    01101
    01106   float SquaredPosDist (const csVector3& pos) const;
    01107
    01113   float SquaredPosMaxDist (const csVector3& pos) const;
    01114
    01126   bool ProjectBox (const csTransform& trans, float fov, float sx, float sy,
    01127         csBox2& sbox, float& min_z, float& max_z) const;
    01128
    01138   bool ProjectOutline (const csTransform& trans, float fov, float sx, float sy,
    01139         csPoly2D& poly, float& min_z, float& max_z) const;
    01140
    01148   bool ProjectOutline (const csVector3& origin,
    01149         int axis, float where, csArray<csVector2>& poly) const;
    01150
    01156   bool ProjectOutline (const csVector3& origin,
    01157         int axis, float where, csPoly2D& poly) const;
    01158
    01171   bool ProjectBoxAndOutline (const csTransform& trans, float fov,
    01172         float sx, float sy, csBox2& sbox, csPoly2D& poly,
    01173         float& min_z, float& max_z) const;
    01174
    01176   csBox3& operator+= (const csBox3& box);
    01178   csBox3& operator+= (const csVector3& point);
    01180   csBox3& operator*= (const csBox3& box);
    01182   bool TestIntersect (const csBox3& box) const;
    01183
    01185   friend CS_CRYSTALSPACE_EXPORT csBox3 operator+ (const csBox3& box1,
    01186     const csBox3& box2);
    01188   friend CS_CRYSTALSPACE_EXPORT csBox3 operator+ (const csBox3& box,
    01189     const csVector3& point);
    01191   friend CS_CRYSTALSPACE_EXPORT csBox3 operator* (const csBox3& box1,
    01192     const csBox3& box2);
    01193
    01195   friend CS_CRYSTALSPACE_EXPORT bool operator== (const csBox3& box1,
    01196     const csBox3& box2);
    01198   friend CS_CRYSTALSPACE_EXPORT bool operator!= (const csBox3& box1,
    01199     const csBox3& box2);
    01201   friend CS_CRYSTALSPACE_EXPORT bool operator< (const csBox3& box1,
    01202     const csBox3& box2);
    01204   friend CS_CRYSTALSPACE_EXPORT bool operator> (const csBox3& box1,
    01205     const csBox3& box2);
    01207   friend CS_CRYSTALSPACE_EXPORT bool operator< (const csVector3& point,
    01208     const csBox3& box);
    01209 };
    01210
    01213 #endif // __CS_BOX_H__