llrect.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:7k
源码类别:

游戏引擎

开发平台:

C++ Builder

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