diff options
Diffstat (limited to 'externals/g3dlite/G3D/Rect2D.h')
| -rw-r--r-- | externals/g3dlite/G3D/Rect2D.h | 417 |
1 files changed, 0 insertions, 417 deletions
diff --git a/externals/g3dlite/G3D/Rect2D.h b/externals/g3dlite/G3D/Rect2D.h deleted file mode 100644 index 2fb58c50465..00000000000 --- a/externals/g3dlite/G3D/Rect2D.h +++ /dev/null @@ -1,417 +0,0 @@ -/** - @file Rect2D.h - - @maintainer Morgan McGuire, http://graphics.cs.williams.edu - - @created 2003-11-13 - @created 2009-11-16 - - Copyright 2000-2009, Morgan McGuire. - All rights reserved. - */ - -#ifndef G3D_Rect2D_h -#define G3D_Rect2D_h - -// Linux defines this as a macro -#ifdef border -#undef border -#endif - -#include "G3D/platform.h" -#include "G3D/Array.h" -#include "G3D/Vector2.h" - -#ifdef _MSC_VER -// Turn off "conditional expression is constant" warning; MSVC generates this -// for debug assertions in inlined methods. -# pragma warning (disable : 4127) -#endif - - -namespace G3D { - -class Any; - -/** - If you are using this class for pixel rectangles, keep in mind that the last - pixel you can draw to is at x0() + width() - 1. - */ -class Rect2D { -private: - Vector2 min, max; - - /** - Returns true if the whole polygon is clipped. - @param p Value of the point - @param axis Index [0 or 1] of the axis to clip along? - @param clipGreater Are we clipping greater than or less than the line? - @param inPoly Polygon being clipped - @param outPoly The clipped polygon - */ - template<class T> - static bool clipSide2D( - const float p, bool clipGreater, int axis, - const Array<T>& inPoly, Array<T>& outPoly) { - - outPoly.clear(); - int i0 = -1; - - Vector2 pt1; - bool c1 = true; - - float negate = clipGreater ? -1 : 1; - - // Find a point that is not clipped - for (i0 = 0; (i0 < inPoly.length()) && c1; ++i0) { - pt1 = inPoly[i0]; - c1 = (negate * pt1[axis]) < (negate * p); - } - - // We incremented i0 one time to many - --i0; - - if (c1) { - // We could not find an unclipped point - return true; - } - - outPoly.append(pt1); - - // for each point in inPoly, - // if the point is outside the side and the previous one was also outside, continue - // if the point is outside the side and the previous one was inside, cut the line - // if the point is inside the side and the previous one was also inside, append the points - // if the point is inside the side and the previous one was outside, cut the line - for (int i = 1; i <= inPoly.length(); ++i) { - T pt2 = inPoly[(i + i0) % inPoly.length()]; - bool c2 = (negate * pt2[axis]) < (negate * p); - - if (c1 ^ c2) { - - if (!c1 && c2 && (i > 1)) { - // Unclipped to clipped trasition and not the first iteration - outPoly.append(pt1); - } - - // only one point is clipped, find where the line crosses the clipping plane - - - float alpha; - if (pt2[axis] == pt1[axis]) { - alpha = 0; - } else { - alpha = (p - pt1[axis]) / (pt2[axis] - pt1[axis]); - } - outPoly.append(pt1.lerp(pt2, alpha)); - } else if (! (c1 || c2) && (i != 1)) { - // neither point is clipped (don't do this the first time - // because we appended the first pt before the loop) - outPoly.append(pt1); - } - - pt1 = pt2; - c1 = c2; - } - - return false; - } - -public: - - /** \param any Must either Rect2D::xywh(#, #, #, #) or Rect2D::xyxy(#, #, #, #)*/ - Rect2D(const Any& any); - - /** Converts the Rect2D to an Any. */ - operator Any() const; - - Rect2D() : min(0, 0), max(0, 0) {} - - /** Creates a rectangle at 0,0 with the given width and height*/ - Rect2D(const Vector2& wh) : min(0, 0), max(wh.x, wh.y) {} - - /** Computes a rectangle that contains both @a a and @a b. - Note that even if @a or @b has zero area, its origin will be included.*/ - Rect2D(const Rect2D& a, const Rect2D& b) { - min = a.min.min(b.min); - max = a.max.max(b.max); - } - - /** @brief Uniformly random point on the interior */ - Vector2 randomPoint() const { - return Vector2(uniformRandom(0, max.x - min.x) + min.x, - uniformRandom(0, max.y - min.y) + min.y); - } - - float width() const { - return max.x - min.x; - } - - float height() const { - return max.y - min.y; - } - - float x0() const { - return min.x; - } - - float x1() const { - return max.x; - } - - float y0() const { - return min.y; - } - - float y1() const { - return max.y; - } - - /** Min, min corner */ - Vector2 x0y0() const { - return min; - } - - Vector2 x1y0() const { - return Vector2(max.x, min.y); - } - - Vector2 x0y1() const { - return Vector2(min.x, max.y); - } - - /** Max,max corner */ - Vector2 x1y1() const { - return max; - } - - /** Width and height */ - Vector2 wh() const { - return max - min; - } - - Vector2 center() const { - return (max + min) * 0.5; - } - - float area() const { - return width() * height(); - } - - bool isFinite() const { - return (min.isFinite() && max.isFinite()); - } - - Rect2D lerp(const Rect2D& other, float alpha) const { - Rect2D out; - - out.min = min.lerp(other.min, alpha); - out.max = max.lerp(other.max, alpha); - - return out; - } - - static Rect2D xyxy(float x0, float y0, float x1, float y1) { - Rect2D r; - - r.min.x = G3D::min(x0, x1); - r.min.y = G3D::min(y0, y1); - r.max.x = G3D::max(x0, x1); - r.max.y = G3D::max(y0, y1); - - return r; - } - - static Rect2D xyxy(const Vector2& v0, const Vector2& v1) { - Rect2D r; - - r.min = v0.min(v1); - r.max = v0.max(v1); - - return r; - } - - static Rect2D xywh(float x, float y, float w, float h) { - return xyxy(x, y, x + w, y + h); - } - - static Rect2D xywh(const Vector2& v, const Vector2& w) { - return xyxy(v.x, v.y, v.x + w.x, v.y + w.y); - } - - /** Constructs a Rect2D with infinite boundaries. - Use isFinite() to test either min or max. - */ - static Rect2D inf() { - return xyxy(Vector2::inf(), Vector2::inf()); - } - - bool contains(const Vector2& v) const { - return (v.x >= min.x) && (v.y >= min.y) && (v.x <= max.x) && (v.y <= max.y); - } - - bool contains(const Rect2D& r) const { - return (min.x <= r.min.x) && (min.y <= r.min.y) && - (max.x >= r.max.x) && (max.y >= r.max.y); - } - - /** True if there is non-zero area to the intersection between @a this and @a r. - Note that two rectangles that are adjacent do not intersect because there is - zero area to the overlap, even though one of them "contains" the corners of the other.*/ - bool intersects(const Rect2D& r) const { - return (min.x < r.max.x) && (min.y < r.max.y) && - (max.x > r.min.x) && (max.y > r.min.y); - } - - /** Like intersection, but counts the adjacent case as touching. */ - bool intersectsOrTouches(const Rect2D& r) const { - return (min.x <= r.max.x) && (min.y <= r.max.y) && - (max.x >= r.min.x) && (max.y >= r.min.y); - } - - Rect2D operator*(float s) const { - return xyxy(min.x * s, min.y * s, max.x * s, max.y * s); - } - - Rect2D operator/(float s) const { - return xyxy(min / s, max / s); - } - - Rect2D operator/(const Vector2& s) const { - return xyxy(min / s, max / s); - } - - Rect2D operator+(const Vector2& v) const { - return xyxy(min + v, max + v); - } - - Rect2D operator-(const Vector2& v) const { - return xyxy(min - v, max - v); - } - - bool operator==(const Rect2D& other) const { - return (min == other.min) && (max == other.max); - } - - bool operator!=(const Rect2D& other) const { - return (min != other.min) || (max != other.max); - } - - /** Returns the corners in the order: (min,min), (max,min), (max,max), (min,max). */ - Vector2 corner(int i) const { - debugAssert(i >= 0 && i < 4); - switch (i & 3) { - case 0: - return Vector2(min.x, min.y); - case 1: - return Vector2(max.x, min.y); - case 2: - return Vector2(max.x, max.y); - case 3: - return Vector2(min.x, max.y); - default: - // Should never get here - return Vector2(0, 0); - } - } - - - /** @deprecated - @sa expand() */ - Rect2D border(float delta) const { - return Rect2D::xywh(x0() + delta, - y0() + delta, - width() - 2.0f * delta, - height() - 2.0f * delta); - } - - /** Returns a new Rect2D that is bigger/smaller by the specified amount - (negative is shrink.) */ - Rect2D expand(float delta) const { - float newX = x0() - delta; - float newY = y0() - delta; - float newW = width() + 2.0f * delta; - float newH = height() + 2.0f * delta; - - if (newW < 0.0f) { - newX = (x0() + width()) / 2.0f; - newW = 0.0f; - } - - if (newH < 0.0f) { - newY = (y0() + height()) / 2.0f; - newH = 0.0f; - } - return Rect2D::xywh(newX, newY, newW, newH); - } - - /** - Clips so that the rightmost point of the outPoly is at rect.x1 (e.g. a 800x600 window produces - rightmost point 799, not 800). The results are suitable for pixel rendering if iRounded. - Templated so that it will work for Vector2,3,4 (the z and w components are interpolated linearly). - The template parameter must define T.lerp and contain x and y components. - - If the entire polygon is clipped by a single side, the result will be empty. - The result might also have zero area but not be empty. - */ - template<class T> - void clip(const Array<T>& inPoly, Array<T>& outPoly) const { - - const bool greaterThan = true; - const bool lessThan = false; - const int X = 0; - const int Y = 1; - - Array<T> temp; - - bool entirelyClipped = - clipSide2D(x0(), lessThan, X, inPoly, temp) || - clipSide2D(x1(), greaterThan, X, temp, outPoly) || - clipSide2D(y0(), lessThan, Y, outPoly, temp) || - clipSide2D(y1(), greaterThan, Y, temp, outPoly); - - if (entirelyClipped) { - outPoly.clear(); - } - } - - - /** Returns the largest, centered Rect2D that can fit inside this - while maintaining the aspect ratio of x:y. Convenient for - displaying images in odd-shaped windows. - */ - Rect2D largestCenteredSubRect(float ww, float hh) const { - float textureAspect = hh / ww; - float viewAspect = height() / width(); - - if (viewAspect > textureAspect) { - // The view is too tall - float h = width() * textureAspect; - float y = (height() - h) / 2; - return Rect2D::xywh(0, y, width(), h) + corner(0); - } else { - // The view is too wide - float w = height() / textureAspect; - float x = (width() - w) / 2; - return Rect2D::xywh(x, 0, w, height()) + corner(0); - } - } - - /** - Returns the overlap region between the two rectangles. This may have zero area - if they do not intersect. See the two-Rect2D constructor for a way to compute - a union-like rectangle. - */ - Rect2D intersect(const Rect2D& other) const { - if (intersects(other)) { - return Rect2D::xyxy(min.max(other.min), max.min(other.max)); - }else{ - return Rect2D::xywh(0, 0, 0, 0); - } - } -}; - -typedef Rect2D AABox2D; -} - -#endif |
