gwnavruntime/math/box2i.h Source File

box2i.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 #pragma once
8 
12 
13 namespace Kaim
14 {
15 
17 class Box2i
18 {
19  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
20 public:
21  // ------------------------------ Functions -----------------------------
22 
23  Box2i() { Clear(); }
24  Box2i(const Vec2i& min_, const Vec2i& max_) : m_min(min_), m_max(max_) { UpdateCountXY(); }
25  Box2i(KyInt32 min_x, KyInt32 min_y, KyInt32 max_x, KyInt32 max_y) : m_min(min_x, min_y), m_max(max_x, max_y) { UpdateCountXY(); }
26 
27  bool operator==(const Box2i& other) const { return other.m_min == m_min && other.m_max == m_max; }
28  bool operator!=(const Box2i& other) const { return other.m_min != m_min || other.m_max != m_max; }
29 
31  void Clear()
32  {
35  ClearCountXY();
36  }
37 
38  bool IsValid() const { return CountX() > 0 && CountY() > 0; }
39 
40  void MakeZero() { m_min.Set(0, 0); m_max.Set(0, 0); UpdateCountXY(); }
41 
42  void Set(const Vec2i& min_, const Vec2i& max_) { m_min = min_; m_max = max_; UpdateCountXY(); }
43 
44  void Set(KyInt32 min_x, KyInt32 min_y, KyInt32 max_x, KyInt32 max_y) { m_min.x = min_x; m_min.y = min_y; m_max.x = max_x; m_max.y = max_y; UpdateCountXY(); }
45  void SetSafe(const Vec2i& min_, const Vec2i& max_) { m_min = min_; m_max = max_; UpdateCountXYSafe(); }
46 
47  void SetMin(const Vec2i& min_) { m_min = min_; UpdateCountXY(); }
48  void SetMax(const Vec2i& max_) { m_max = max_; UpdateCountXY(); }
49 
50  const Vec2i& Min() const { return m_min; }
51  const Vec2i& Max() const { return m_max; }
52 
53  const Vec2i& CountXY() const { return m_countXY; }
54 
55  KyInt32 CountX() const { return m_countXY.x; }
56  KyInt32 CountY() const { return m_countXY.y; }
57 
58  // ------------------------------ East North West South -----------------------------
59 
60  KyInt32 East() const { return m_max.x; }
61  KyInt32 North() const { return m_max.y; }
62  KyInt32 West() const { return m_min.x; }
63  KyInt32 South() const { return m_max.y; }
64 
65  Vec2i NorthEast() const { return m_max; }
66  Vec2i NorthWest() const { return Vec2i(m_min.x, m_max.y); }
67  Vec2i SouthWest() const { return m_min; }
68  Vec2i SouthEast() const { return Vec2i(m_max.x, m_min.y); }
69 
70  // ------------------------------ DoesContain -----------------------------
71 
72  bool DoesContain(const Vec2i& pos) const { return pos.x >= m_min.x && pos.x <= m_max.x && pos.y >= m_min.y && pos.y <= m_max.y; }
73 
74  bool DoesContainStrictly(const Vec2i& pos) const { return pos.x > m_min.x && pos.x < m_max.x && pos.y > m_min.y && pos.y < m_max.y; }
75 
77  bool DoesContainNeighbor(const Vec2i& pos, CardinalDir dir) const
78  {
79  switch (dir)
80  {
81  case CardinalDir_EAST: return pos.x < m_max.x;
82  case CardinalDir_NORTH: return pos.y < m_max.y;
83  case CardinalDir_WEST: return pos.x > m_min.x;
84  default: /*CardinalDir_SOUTH*/ return pos.y > m_min.y;
85  }
86  }
87 
88  // ------------------------------ Index -----------------------------
89 
101  KyInt32 GetRowMajorIndex(const Vec2i& pos) const { return (pos.y - m_min.y) * CountX() + pos.x - m_min.x; }
102 
105  KyInt32 GetRowMajorIndexFromLocalPos(const Vec2i& localPos) const { return localPos.y * CountX() + localPos.x; }
106 
107  // ------------------------------ Expand -----------------------------
108 
109  void ExpandByPos(const Vec2i& pos)
110  {
111  ExpandByVec2_MinMaxOnly(pos);
112  UpdateCountXY();
113  }
114 
115  void ExpandByPos(const Vec3i& pos)
116  {
117  ExpandByVec3_MinMaxOnly(pos);
118  UpdateCountXY();
119  }
120 
121  void ExpandByTriangle(const Triangle3i& triangle)
122  {
123  ExpandByVec3_MinMaxOnly(triangle.A);
124  ExpandByVec3_MinMaxOnly(triangle.B);
125  ExpandByVec3_MinMaxOnly(triangle.C);
126  UpdateCountXY();
127  }
128 
129  void ExpandByBox(const Box2i& box)
130  {
131  m_min.x = Kaim::Min(m_min.x, box.m_min.x);
132  m_max.x = Kaim::Max(m_max.x, box.m_max.x);
133  m_min.y = Kaim::Min(m_min.y, box.m_min.y);
134  m_max.y = Kaim::Max(m_max.y, box.m_max.y);
135  UpdateCountXY();
136  }
137 
138  // ------------------------------ Enlarge -----------------------------
139 
140  void Enlarge(KyInt32 enlargement)
141  {
142  Vec2i e(enlargement, enlargement);
143  m_min -= e;
144  m_max += e;
145  UpdateCountXY();
146  }
147 
148  void GetEnlarged(KyInt32 enlargement, Box2i& enlarged) const
149  {
150  enlarged = *this;
151  enlarged.Enlarge(enlargement);
152  }
153 
154  Box2i GetEnlarged(KyInt32 enlargement) const
155  {
156  Vec2i e(enlargement, enlargement);
157  return Box2i(m_min - e, m_max + e);
158  }
159 
160  // ------------------------------ Intersect -----------------------------
161 
163  bool IntersectWith(const Box2i& box) { return this->SetAsIntersection(*this, box); }
164 
165  bool DoesIntersectWith(const Box2i& box) const
166  {
167  KyInt32 min_x = Kaim::Max(m_min.x, box.m_min.x);
168  KyInt32 max_x = Kaim::Min(m_max.x, box.m_max.x);
169  KyInt32 min_y = Kaim::Max(m_min.y, box.m_min.y);
170  KyInt32 max_y = Kaim::Min(m_max.y, box.m_max.y);
171  return (min_x <= max_x && min_y <= max_y);
172  }
173 
175  bool SetAsIntersection(const Box2i& box_1, const Box2i& box_2)
176  {
177  m_min.x = Kaim::Max(box_1.m_min.x, box_2.m_min.x);
178  m_max.x = Kaim::Min(box_1.m_max.x, box_2.m_max.x);
179  m_min.y = Kaim::Max(box_1.m_min.y, box_2.m_min.y);
180  m_max.y = Kaim::Min(box_1.m_max.y, box_2.m_max.y);
181 
182  if (m_min.x <= m_max.x && m_min.y <= m_max.y)
183  {
184  UpdateCountXY();
185  return true;
186  }
187 
188  Clear();
189  return false;
190  }
191 
192 private:
193  void UpdateCountX() { m_countXY.x = m_max.x - m_min.x + 1; }
194  void UpdateCountY() { m_countXY.y = m_max.y - m_min.y + 1; }
195  void UpdateCountXY() { UpdateCountX(); UpdateCountY(); }
196  void ClearCountXY() { m_countXY.x = -1; m_countXY.y = -1; }
197 
198  void UpdateCountXYSafe()
199  {
200  KyInt64 countX = (KyInt64)m_max.x - (KyInt64)m_min.x + 1;
201  KyInt64 countY = (KyInt64)m_max.y - (KyInt64)m_min.y + 1;
202  if (countX < 0 || countY < 0 || countX > KyInt32MAXVAL || countY > KyInt32MAXVAL)
203  {
204  Clear();
205  return;
206  }
207 
208  m_countXY.x = (KyInt32)countX;
209  m_countXY.y = (KyInt32)countY;
210  }
211 
212  void ExpandByVec2_MinMaxOnly(const Vec2i& pos)
213  {
214  const KyInt32 posx = pos.x;
215  const KyInt32 posy = pos.y;
216  m_min.x = Kaim::Min(m_min.x, posx);
217  m_max.x = Kaim::Max(m_max.x, posx);
218  m_min.y = Kaim::Min(m_min.y, posy);
219  m_max.y = Kaim::Max(m_max.y, posy);
220  }
221 
222  void ExpandByVec3_MinMaxOnly(const Vec3i& pos)
223  {
224  const KyInt32 posx = pos.x;
225  const KyInt32 posy = pos.y;
226  m_min.x = Kaim::Min(m_min.x, posx);
227  m_max.x = Kaim::Max(m_max.x, posx);
228  m_min.y = Kaim::Min(m_min.y, posy);
229  m_max.y = Kaim::Max(m_max.y, posy);
230  }
231 
232 public:
233  // ------------------------------ Public Data -----------------------------
234  Vec2i m_min;
235  Vec2i m_max;
236 
237 private:
238  Vec2i m_countXY;
239 
240  friend void SwapEndianness(Endianness::Target e, Box2i& self);
241  friend class GridUtils;
242 };
243 
244 inline void SwapEndianness(Endianness::Target e, Box2i& self)
245 {
246  SwapEndianness(e, self.m_min);
247  SwapEndianness(e, self.m_max);
248  SwapEndianness(e, self.m_countXY);
249 }
250 
251 template <class OSTREAM>
252 inline OSTREAM& operator<<(OSTREAM& os, const Box2i& self)
253 {
254  os << "{" << self.Min() << "," << self.Max() << "}";
255  return os;
256 }
257 
258 }
259 
260 
261 
void MakeZero()
set {{0,0},{0,0}}
Definition: box2i.h:40
#define KyInt32MINVAL
KyInt32 min value
Definition: types.h:61
static const CardinalDir CardinalDir_NORTH
Y positive axis.
Definition: cardinaldir.h:17
2d axis aligned box of 32bits integers. Very Important: CountX() returns m_max.x - m_min...
Definition: box2i.h:17
bool DoesContainNeighbor(const Vec2i &pos, CardinalDir dir) const
precondition: pos is inside
Definition: box2i.h:77
void SetSafe(const Vec2i &min_, const Vec2i &max_)
check if values max_ - min_ does overflow
Definition: box2i.h:45
void Set(KyInt32 _x, KyInt32 _y)
Sets x=_x and y=_y.
Definition: vec2i.h:29
Box2i()
Set { {+infinite, +infinite}, {-infinite, -infinite} }.
Definition: box2i.h:23
KyUInt32 CardinalDir
Defines a type that refers to one of the cardinal points on the compass:
Definition: cardinaldir.h:15
bool IntersectWith(const Box2i &box)
Sets itself as its intersection with box, return true if itself and box do intersect.
Definition: box2i.h:163
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:132
static const CardinalDir CardinalDir_EAST
X positive axis.
Definition: cardinaldir.h:16
Target
Enumerates the possible endianness types relative to the current platform.
Definition: endianness.h:27
KyInt32 GetRowMajorIndex(const Vec2i &pos) const
Compute index of position in box, where index is incremented in a outer-loop on Y and inner-loop on X...
Definition: box2i.h:101
std::int64_t KyInt64
int64_t
Definition: types.h:25
#define KyInt32MAXVAL
KyInt32 max value
Definition: types.h:60
bool SetAsIntersection(const Box2i &box_1, const Box2i &box_2)
Sets itself as the intersection of box_1 and box_2, return true if box_1 and box_2 do intersect...
Definition: box2i.h:175
static const CardinalDir CardinalDir_WEST
X negative axis.
Definition: cardinaldir.h:18
2d vector using KyInt32
Definition: vec2i.h:18
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
KyInt32 CountY() const
Return m_max.y - m_min.y + 1.
Definition: box2i.h:56
KyInt32 GetRowMajorIndexFromLocalPos(const Vec2i &localPos) const
Compute index of position in box, where index is incremented in a outer-loop on Y and inner-loop on X...
Definition: box2i.h:105
std::int32_t KyInt32
int32_t
Definition: types.h:24
const Vec2i & CountXY() const
Return { m_max.x - m_min.x + 1, m_max.y - m_min.y + 1}.
Definition: box2i.h:53
KyInt32 CountX() const
Return m_max.x - m_min.x + 1.
Definition: box2i.h:55
void Clear()
Set { {+infinite, +infinite}, {-infinite, -infinite} }.
Definition: box2i.h:31