aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/llrect.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llmath/llrect.h')
-rw-r--r--linden/indra/llmath/llrect.h289
1 files changed, 289 insertions, 0 deletions
diff --git a/linden/indra/llmath/llrect.h b/linden/indra/llmath/llrect.h
new file mode 100644
index 0000000..fd45d3c
--- /dev/null
+++ b/linden/indra/llmath/llrect.h
@@ -0,0 +1,289 @@
1/**
2 * @file llrect.h
3 * @brief A rectangle in GL coordinates, with bottom,left = 0,0
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28
29#ifndef LL_LLRECT_H
30#define LL_LLRECT_H
31
32#include <iostream>
33#include "llmath.h"
34#include "llsd.h"
35
36// Top > Bottom due to GL coords
37template <class Type> class LLRectBase
38{
39public:
40 Type mLeft;
41 Type mTop;
42 Type mRight;
43 Type mBottom;
44
45 // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect
46 Type getWidth() const { return mRight - mLeft; }
47 Type getHeight() const { return mTop - mBottom; }
48 Type getCenterX() const { return (mLeft + mRight) / 2; }
49 Type getCenterY() const { return (mTop + mBottom) / 2; }
50
51 LLRectBase(): mLeft(0), mTop(0), mRight(0), mBottom(0)
52 {}
53
54 LLRectBase(const LLRectBase &r):
55 mLeft(r.mLeft), mTop(r.mTop), mRight(r.mRight), mBottom(r.mBottom)
56 {}
57
58 LLRectBase(Type left, Type top, Type right, Type bottom):
59 mLeft(left), mTop(top), mRight(right), mBottom(bottom)
60 {}
61
62 LLRectBase(const LLSD& sd)
63 {
64 setValue(sd);
65 }
66
67 const LLRectBase& operator=(const LLSD& sd)
68 {
69 setValue(sd);
70 return *this;
71 }
72
73 void setValue(const LLSD& sd)
74 {
75 mLeft = sd[0].asInteger();
76 mTop = sd[1].asInteger();
77 mRight = sd[2].asInteger();
78 mBottom = sd[3].asInteger();
79 }
80
81 LLSD getValue() const
82 {
83 LLSD ret;
84 ret[0] = mLeft;
85 ret[1] = mTop;
86 ret[2] = mRight;
87 ret[3] = mBottom;
88 return ret;
89 }
90
91 // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect
92 BOOL pointInRect(const Type x, const Type y) const
93 {
94 return mLeft <= x && x < mRight &&
95 mBottom <= y && y < mTop;
96 }
97
98 //// Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect
99 BOOL localPointInRect(const Type x, const Type y) const
100 {
101 return 0 <= x && x < getWidth() &&
102 0 <= y && y < getHeight();
103 }
104
105 void clampPointToRect(Type& x, Type& y)
106 {
107 x = llclamp(x, mLeft, mRight);
108 y = llclamp(y, mBottom, mTop);
109 }
110
111 void clipPointToRect(const Type start_x, const Type start_y, Type& end_x, Type& end_y)
112 {
113 if (!pointInRect(start_x, start_y))
114 {
115 return;
116 }
117 Type clip_x = 0;
118 Type clip_y = 0;
119 Type delta_x = end_x - start_x;
120 Type delta_y = end_y - start_y;
121 if (end_x > mRight) clip_x = end_x - mRight;
122 if (end_x < mLeft) clip_x = end_x - mLeft;
123 if (end_y > mTop) clip_y = end_y - mTop;
124 if (end_y < mBottom) clip_y = end_y - mBottom;
125 // clip_? and delta_? should have same sign, since starting point is in rect
126 // so ratios will be positive
127 F32 ratio_x = ((F32)clip_x / (F32)delta_x);
128 F32 ratio_y = ((F32)clip_y / (F32)delta_y);
129 if (ratio_x > ratio_y)
130 {
131 // clip along x direction
132 end_x -= (Type)(clip_x);
133 end_y -= (Type)(delta_y * ratio_x);
134 }
135 else
136 {
137 // clip along y direction
138 end_x -= (Type)(delta_x * ratio_y);
139 end_y -= (Type)clip_y;
140 }
141 }
142
143 // Note: Does NOT follow GL_QUAD conventions: the top and right edges ARE considered part of the rect
144 // returns TRUE if any part of rect is is inside this LLRect
145 BOOL rectInRect(const LLRectBase* rect) const
146 {
147 return mLeft <= rect->mRight && rect->mLeft <= mRight &&
148 mBottom <= rect->mTop && rect->mBottom <= mTop ;
149 }
150
151 void set(Type left, Type top, Type right, Type bottom)
152 {
153 mLeft = left;
154 mTop = top;
155 mRight = right;
156 mBottom = bottom;
157 }
158
159 // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect
160 void setOriginAndSize( Type left, Type bottom, Type width, Type height)
161 {
162 mLeft = left;
163 mTop = bottom + height;
164 mRight = left + width;
165 mBottom = bottom;
166 }
167
168 // Note: follows GL_QUAD conventions: the top and right edges are not considered part of the rect
169 void setLeftTopAndSize( Type left, Type top, Type width, Type height)
170 {
171 mLeft = left;
172 mTop = top;
173 mRight = left + width;
174 mBottom = top - height;
175 }
176
177 void setCenterAndSize(Type x, Type y, Type width, Type height)
178 {
179 mLeft = x - width/2;
180 mTop = y + height/2;
181 mRight = x + width/2;
182 mBottom = y - height/2;
183 }
184
185
186 void translate(Type horiz, Type vertical)
187 {
188 mLeft += horiz;
189 mRight += horiz;
190 mTop += vertical;
191 mBottom += vertical;
192 }
193
194 void stretch( Type dx, Type dy)
195 {
196 mLeft -= dx;
197 mRight += dx;
198 mTop += dy;
199 mBottom -= dy;
200 makeValid();
201 }
202
203 void stretch( Type delta )
204 {
205 stretch(delta, delta);
206
207 }
208
209 void makeValid()
210 {
211 mLeft = llmin(mLeft, mRight);
212 mBottom = llmin(mBottom, mTop);
213 }
214
215 friend const LLRectBase& operator|=(LLRectBase &a, const LLRectBase &b) // Return rect including a & b
216 {
217 a.mLeft = llmin(a.mLeft, b.mLeft);
218 a.mRight = llmax(a.mRight, b.mRight);
219 a.mBottom = llmin(a.mBottom, b.mBottom);
220 a.mTop = llmax(a.mTop, b.mTop);
221 return a;
222 }
223
224 friend LLRectBase operator|(const LLRectBase &a, const LLRectBase &b) // Return rect including a & b
225 {
226 LLRectBase<Type> result;
227 result.mLeft = llmin(a.mLeft, b.mLeft);
228 result.mRight = llmax(a.mRight, b.mRight);
229 result.mBottom = llmin(a.mBottom, b.mBottom);
230 result.mTop = llmax(a.mTop, b.mTop);
231 return result;
232 }
233
234 friend const LLRectBase& operator&=(LLRectBase &a, const LLRectBase &b) // set a to rect where a intersects b
235 {
236 a.mLeft = llmax(a.mLeft, b.mLeft);
237 a.mRight = llmin(a.mRight, b.mRight);
238 a.mBottom = llmax(a.mBottom, b.mBottom);
239 a.mTop = llmin(a.mTop, b.mTop);
240 if (a.mLeft > a.mRight)
241 {
242 a.mLeft = a.mRight;
243 }
244 if (a.mBottom > a.mTop)
245 {
246 a.mBottom = a.mTop;
247 }
248 return a;
249 }
250
251 friend LLRectBase operator&(const LLRectBase &a, const LLRectBase &b) // Return rect where a intersects b
252 {
253 LLRectBase result = a;
254 result &= b;
255 return result;
256 }
257
258 friend std::ostream &operator<<(std::ostream &s, const LLRectBase &rect)
259 {
260 s << "{ L " << rect.mLeft << " B " << rect.mBottom
261 << " W " << rect.getWidth() << " H " << rect.getHeight() << " }";
262 return s;
263 }
264
265 bool operator==(const LLRectBase &b)
266 {
267 return ((mLeft == b.mLeft) &&
268 (mTop == b.mTop) &&
269 (mRight == b.mRight) &&
270 (mBottom == b.mBottom));
271 }
272
273 bool operator!=(const LLRectBase &b)
274 {
275 return ((mLeft != b.mLeft) ||
276 (mTop != b.mTop) ||
277 (mRight != b.mRight) ||
278 (mBottom != b.mBottom));
279 }
280
281 static LLRectBase<Type> null;
282};
283
284template <class Type> LLRectBase<Type> LLRectBase<Type>::null(0,0,0,0);
285
286typedef LLRectBase<S32> LLRect;
287typedef LLRectBase<F32> LLRectf;
288
289#endif