llrect.h

Go to the documentation of this file.
00001 
00033 #ifndef LL_LLRECT_H
00034 #define LL_LLRECT_H
00035 
00036 #include <iostream>
00037 #include "llmath.h"
00038 #include "llsd.h"
00039 
00040 // Top > Bottom due to GL coords
00041 template <class Type> class LLRectBase
00042 {
00043 public:
00044         Type            mLeft;
00045         Type            mTop;
00046         Type            mRight;
00047         Type            mBottom;
00048 
00049         // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect
00050         Type            getWidth()      const { return mRight - mLeft; }
00051         Type            getHeight()     const { return mTop - mBottom; }
00052         Type            getCenterX() const { return (mLeft + mRight) / 2; }
00053         Type            getCenterY() const { return (mTop + mBottom) / 2; }
00054 
00055         LLRectBase():   mLeft(0), mTop(0), mRight(0), mBottom(0)
00056         {}
00057 
00058         LLRectBase(const LLRectBase &r):
00059         mLeft(r.mLeft), mTop(r.mTop), mRight(r.mRight), mBottom(r.mBottom)
00060         {}
00061 
00062         LLRectBase(Type left, Type top, Type right, Type bottom):
00063         mLeft(left), mTop(top), mRight(right), mBottom(bottom)
00064         {}
00065 
00066         LLRectBase(const LLSD& sd)
00067         {
00068                 setValue(sd);
00069         }
00070 
00071         const LLRectBase& operator=(const LLSD& sd)
00072         {
00073                 setValue(sd);
00074                 return *this;
00075         }
00076 
00077         void setValue(const LLSD& sd)
00078         {
00079                 mLeft = sd[0].asInteger(); 
00080                 mTop = sd[1].asInteger();
00081                 mRight = sd[2].asInteger();
00082                 mBottom = sd[3].asInteger();
00083         }
00084 
00085         LLSD getValue() const
00086         {
00087                 LLSD ret;
00088                 ret[0] = mLeft;
00089                 ret[1] = mTop;
00090                 ret[2] = mRight;
00091                 ret[3] = mBottom;
00092                 return ret;
00093         }
00094 
00095         // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect
00096         BOOL            pointInRect(const Type x, const Type y) const
00097         {
00098                 return  mLeft <= x && x < mRight &&
00099                                 mBottom <= y && y < mTop;
00100         }
00101 
00103         BOOL            localPointInRect(const Type x, const Type y) const
00104         {
00105                 return  0 <= x && x < getWidth() &&
00106                                 0 <= y && y < getHeight();
00107         }
00108 
00109         void            clampPointToRect(Type& x, Type& y)
00110         {
00111                 x = llclamp(x, mLeft, mRight);
00112                 y = llclamp(y, mBottom, mTop);
00113         }
00114 
00115         void            clipPointToRect(const Type start_x, const Type start_y, Type& end_x, Type& end_y)
00116         {
00117                 if (!pointInRect(start_x, start_y))
00118                 {
00119                         return;
00120                 }
00121                 Type clip_x = 0;
00122                 Type clip_y = 0;
00123                 Type delta_x = end_x - start_x;
00124                 Type delta_y = end_y - start_y;
00125                 if (end_x > mRight) clip_x = end_x - mRight;
00126                 if (end_x < mLeft) clip_x = end_x - mLeft;
00127                 if (end_y > mTop) clip_y = end_y - mTop;
00128                 if (end_y < mBottom) clip_y = end_y - mBottom;
00129                 // clip_? and delta_? should have same sign, since starting point is in rect
00130                 // so ratios will be positive
00131                 F32 ratio_x = ((F32)clip_x / (F32)delta_x);
00132                 F32 ratio_y = ((F32)clip_y / (F32)delta_y);
00133                 if (ratio_x > ratio_y)
00134                 {
00135                         // clip along x direction
00136                         end_x -= (Type)(clip_x);
00137                         end_y -= (Type)(delta_y * ratio_x);
00138                 }
00139                 else
00140                 {
00141                         // clip along y direction
00142                         end_x -= (Type)(delta_x * ratio_y);
00143                         end_y -= (Type)clip_y;
00144                 }
00145         }
00146 
00147         // Note: Does NOT follow GL_QUAD conventions: the top and right edges ARE considered part of the rect
00148         // returns TRUE if any part of rect is is inside this LLRect
00149         BOOL            rectInRect(const LLRectBase* rect) const
00150         {
00151                 return mLeft <= rect->mRight && rect->mLeft <= mRight && 
00152                            mBottom <= rect->mTop && rect->mBottom <= mTop ;
00153         }
00154 
00155         void            set(Type left, Type top, Type right, Type bottom)
00156         {
00157                 mLeft = left;
00158                 mTop = top;
00159                 mRight = right;
00160                 mBottom = bottom;
00161         }
00162 
00163         // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect
00164         void            setOriginAndSize( Type left, Type bottom, Type width, Type height)
00165         {
00166                 mLeft = left;
00167                 mTop = bottom + height;
00168                 mRight = left + width;
00169                 mBottom = bottom;
00170         }
00171 
00172         // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect
00173         void            setLeftTopAndSize( Type left, Type top, Type width, Type height)
00174         {
00175                 mLeft = left;
00176                 mTop = top;
00177                 mRight = left + width;
00178                 mBottom = top - height;
00179         }
00180 
00181         void setCenterAndSize(Type x, Type y, Type width, Type height)
00182         {
00183                 mLeft = x - width/2;
00184                 mTop = y + height/2;
00185                 mRight = x + width/2;
00186                 mBottom = y - height/2;
00187         }
00188 
00189 
00190         void            translate(Type horiz, Type vertical)
00191         {
00192                 mLeft += horiz;
00193                 mRight += horiz;
00194                 mTop += vertical;
00195                 mBottom += vertical;
00196         }
00197 
00198         void    stretch( Type dx, Type dy)
00199         {
00200                 mLeft -= dx;
00201                 mRight += dx;
00202                 mTop += dy;
00203                 mBottom -= dy;
00204                 makeValid();
00205         }
00206         
00207         void    stretch( Type delta )
00208         {
00209                 stretch(delta, delta);
00210                 
00211         }
00212         
00213         void  makeValid()
00214         {
00215                 mLeft = llmin(mLeft, mRight);
00216                 mBottom = llmin(mBottom, mTop);
00217         }
00218         
00219         void unionWith(const LLRectBase &other)
00220         {
00221                 mLeft = llmin(mLeft, other.mLeft);
00222                 mRight = llmax(mRight, other.mRight);
00223                 mBottom = llmin(mBottom, other.mBottom);
00224                 mTop = llmax(mTop, other.mTop);
00225         }
00226 
00227         void intersectWith(const LLRectBase &other)
00228         {
00229                 mLeft = llmax(mLeft, other.mLeft);
00230                 mRight = llmin(mRight, other.mRight);
00231                 mBottom = llmax(mBottom, other.mBottom);
00232                 mTop = llmin(mTop, other.mTop);
00233                 if (mLeft > mRight)
00234                 {
00235                         mLeft = mRight;
00236                 }
00237                 if (mBottom > mTop)
00238                 {
00239                         mBottom = mTop;
00240                 }
00241         }
00242 
00243         friend std::ostream &operator<<(std::ostream &s, const LLRectBase &rect)
00244         {
00245                 s << "{ L " << rect.mLeft << " B " << rect.mBottom
00246                         << " W " << rect.getWidth() << " H " << rect.getHeight() << " }";
00247                 return s;
00248         }
00249 
00250         bool operator==(const LLRectBase &b)
00251         {
00252                 return ((mLeft == b.mLeft) &&
00253                                 (mTop == b.mTop) &&
00254                                 (mRight == b.mRight) &&
00255                                 (mBottom == b.mBottom));
00256         }
00257 
00258         bool operator!=(const LLRectBase &b)
00259         {
00260                 return ((mLeft != b.mLeft) ||
00261                                 (mTop != b.mTop) ||
00262                                 (mRight != b.mRight) ||
00263                                 (mBottom != b.mBottom));
00264         }
00265 
00266         static LLRectBase<Type> null;
00267 };
00268 
00269 template <class Type> LLRectBase<Type> LLRectBase<Type>::null(0,0,0,0);
00270 
00271 typedef LLRectBase<S32> LLRect;
00272 typedef LLRectBase<F32> LLRectf;
00273 
00274 #endif

Generated on Thu Jul 1 06:09:04 2010 for Second Life Viewer by  doxygen 1.4.7