Isle
Loading...
Searching...
No Matches
mxregion.cpp
Go to the documentation of this file.
1#include "mxregion.h"
2
3#include <limits.h>
4
9
10// FUNCTION: LEGO1 0x100c31c0
11// FUNCTION: BETA10 0x10148f00
13{
14 m_spanList = new MxSpanList;
15 m_boundingRect = MxRect32(INT_MAX, INT_MAX, -1, -1);
16}
17
18// FUNCTION: LEGO1 0x100c3690
19// FUNCTION: BETA10 0x10148fe8
21{
22 delete m_spanList;
23}
24
25// FUNCTION: LEGO1 0x100c3700
26// FUNCTION: BETA10 0x1014907a
28{
30 m_boundingRect = MxRect32(INT_MAX, INT_MAX, -1, -1);
31}
32
33// FUNCTION: LEGO1 0x100c3750
34// FUNCTION: BETA10 0x101490bd
36{
37 MxRect32 rect(p_rect);
38 MxRect32 newRect;
40 MxSpan* span;
41
42 while (!rect.Empty() && cursor.Next(span)) {
43 if (span->GetMin() >= rect.GetBottom()) {
44 MxSpan* newSpan = new MxSpan(rect);
45 cursor.Prepend(newSpan);
46 rect.SetTop(rect.GetBottom());
47 }
48 else if (rect.GetTop() < span->GetMax()) {
49 if (rect.GetTop() < span->GetMin()) {
50 newRect = rect;
51 newRect.SetBottom(span->GetMin());
52 MxSpan* newSpan = new MxSpan(newRect);
53 cursor.Prepend(newSpan);
54 rect.SetTop(span->GetMin());
55 }
56 else if (span->GetMin() < rect.GetTop()) {
57 MxSpan* newSpan = span->Clone();
58 newSpan->SetMax(rect.GetTop());
59 span->SetMin(rect.GetTop());
60 cursor.Prepend(newSpan);
61 }
62
63 if (rect.GetBottom() < span->GetMax()) {
64 MxSpan* newSpan = span->Clone();
65 newSpan->SetMax(rect.GetBottom());
66 span->SetMin(rect.GetBottom());
67 newSpan->AddSegment(rect.GetLeft(), rect.GetRight());
68 cursor.Prepend(newSpan);
69 rect.SetTop(rect.GetBottom());
70 }
71 else {
72 span->AddSegment(rect.GetLeft(), rect.GetRight());
73 rect.SetTop(span->GetMax());
74 }
75 }
76 }
77
78 if (!rect.Empty()) {
79 MxSpan* newSpan = new MxSpan(rect);
80 m_spanList->Append(newSpan);
81 }
82
83 m_boundingRect |= p_rect;
84}
85
86// FUNCTION: LEGO1 0x100c3e20
87// FUNCTION: BETA10 0x10149535
89{
90 if (!m_boundingRect.Intersects(p_rect)) {
91 return FALSE;
92 }
93
95 MxSpan* span;
96
97 while (cursor.Next(span)) {
98 if (span->GetMin() >= p_rect.GetBottom()) {
99 return FALSE;
100 }
101
102 if (span->GetMax() > p_rect.GetTop() && span->IntersectsH(p_rect)) {
103 return TRUE;
104 }
105 }
106
107 return FALSE;
108}
109
110// FUNCTION: LEGO1 0x100c3f70
111// FUNCTION: BETA10 0x10149663
113{
114 m_region = p_region;
115 m_rect = NULL;
118}
119
120// FUNCTION: LEGO1 0x100c40b0
122{
123 if (m_rect) {
124 delete m_rect;
125 }
126
127 if (m_spanListCursor) {
128 delete m_spanListCursor;
129 }
130
131 if (m_segListCursor) {
132 delete m_segListCursor;
133 }
134}
135
136// FUNCTION: LEGO1 0x100c4140
138{
140
141 MxSpan* span;
142 if (m_spanListCursor->Current(span)) {
144
145 MxSegment* segment;
146 m_segListCursor->First(segment);
147
148 SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
149 }
150 else {
151 Reset();
152 }
153
154 return m_rect;
155}
156
157// FUNCTION: LEGO1 0x100c41d0
159{
161
162 MxSpan* span;
163 if (m_spanListCursor->Current(span)) {
165
166 MxSegment* segment;
167 m_segListCursor->Last(segment);
168
169 SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
170 }
171 else {
172 Reset();
173 }
174
175 return m_rect;
176}
177
178// FUNCTION: LEGO1 0x100c4260
180{
181 MxSegment* segment;
182 MxSpan* span;
183
184 if (m_segListCursor && m_segListCursor->Next(segment)) {
186
187 SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
188 return m_rect;
189 }
190
191 if (m_spanListCursor->Next(span)) {
193 m_segListCursor->First(segment);
194
195 SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
196 return m_rect;
197 }
198
199 Reset();
200 return m_rect;
201}
202
203// FUNCTION: LEGO1 0x100c4360
205{
206 MxSegment* segment;
207 MxSpan* span;
208
209 if (m_segListCursor && m_segListCursor->Prev(segment)) {
211
212 SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
213 return m_rect;
214 }
215
216 if (m_spanListCursor->Prev(span)) {
218 m_segListCursor->Last(segment);
219
220 SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
221 return m_rect;
222 }
223
224 Reset();
225 return m_rect;
226}
227
228// FUNCTION: LEGO1 0x100c4460
230{
232 NextSpan(p_rect);
233 return m_rect;
234}
235
236// FUNCTION: LEGO1 0x100c4480
238{
240 PrevSpan(p_rect);
241 return m_rect;
242}
243
244// FUNCTION: LEGO1 0x100c44a0
246{
247 MxSegment* segment;
248
249 if (m_segListCursor && m_segListCursor->Next(segment)) {
250 MxSpan* span;
251
253
254 if (span->IntersectsV(p_rect) && segment->IntersectsH(p_rect)) {
255 SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
256 *m_rect &= p_rect;
257 }
258 else {
259 NextSpan(p_rect);
260 }
261 }
262 else {
263 NextSpan(p_rect);
264 }
265
266 return m_rect;
267}
268
269// FUNCTION: LEGO1 0x100c4590
271{
272 MxSegment* segment;
273
274 if (m_segListCursor && m_segListCursor->Prev(segment)) {
275 MxSpan* span;
276
278
279 if (span->IntersectsV(p_rect) && segment->IntersectsH(p_rect)) {
280 SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
281 *m_rect &= p_rect;
282 }
283 else {
284 PrevSpan(p_rect);
285 }
286 }
287 else {
288 PrevSpan(p_rect);
289 }
290
291 return m_rect;
292}
293
294// FUNCTION: LEGO1 0x100c4680
296{
297 if (m_rect) {
298 delete m_rect;
299 m_rect = NULL;
300 }
301
303
304 if (m_segListCursor) {
305 delete m_segListCursor;
307 }
308}
309
310// FUNCTION: LEGO1 0x100c46c0
312{
313 if (m_segListCursor) {
314 delete m_segListCursor;
315 }
316
317 m_segListCursor = new MxSegmentListCursor(p_segList);
318}
319
320// FUNCTION: LEGO1 0x100c4980
321void MxRegionCursor::SetRect(MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom)
322{
323 if (!m_rect) {
324 m_rect = new MxRect32;
325 }
326
327 m_rect->SetLeft(p_left);
328 m_rect->SetTop(p_top);
329 m_rect->SetRight(p_right);
330 m_rect->SetBottom(p_bottom);
331}
332
333// FUNCTION: LEGO1 0x100c4a20
335{
336 MxSpan* span;
337 while (m_spanListCursor->Next(span)) {
338 if (p_rect.GetBottom() <= span->GetMin()) {
339 Reset();
340 return;
341 }
342
343 if (p_rect.GetTop() < span->GetMax()) {
345
346 MxSegment* segment;
347 while (m_segListCursor->Next(segment)) {
348 if (p_rect.GetRight() <= segment->GetMin()) {
349 break;
350 }
351
352 if (p_rect.GetLeft() < segment->GetMax()) {
353 SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
354 *m_rect &= p_rect;
355 return;
356 }
357 }
358 }
359 }
360
361 Reset();
362}
363
364// FUNCTION: LEGO1 0x100c4b50
366{
367 MxSpan* span;
368 while (m_spanListCursor->Prev(span)) {
369 if (span->GetMax() <= p_rect.GetTop()) {
370 Reset();
371 return;
372 }
373
374 if (span->GetMin() < p_rect.GetBottom()) {
376
377 MxSegment* segment;
378 while (m_segListCursor->Prev(segment)) {
379 if (segment->GetMax() <= p_rect.GetLeft()) {
380 break;
381 }
382
383 if (segment->GetMin() < p_rect.GetRight()) {
384 SetRect(segment->GetMin(), span->GetMin(), segment->GetMax(), span->GetMax());
385 *m_rect &= p_rect;
386 return;
387 }
388 }
389 }
390 }
391
392 Reset();
393}
394
395// FUNCTION: LEGO1 0x100c4c90
397{
398 m_min = p_min;
399 m_max = p_max;
401}
402
403// FUNCTION: LEGO1 0x100c50e0
404// FUNCTION: BETA10 0x1014a2d6
406{
407 m_min = p_rect.GetTop();
408 m_max = p_rect.GetBottom();
410
411 MxSegment* segment = new MxSegment(p_rect.GetLeft(), p_rect.GetRight());
412 m_segList->Append(segment);
413}
414
415// FUNCTION: LEGO1 0x100c5280
416// FUNCTION: BETA10 0x1014a3fc
418{
421
422 MxSegment* segment;
423 while (a.Next(segment) && segment->GetMax() < p_min) {
424 ;
425 }
426
427 if (a.HasMatch()) {
428 if (p_min > segment->GetMin()) {
429 p_min = segment->GetMin();
430 }
431
432 while (segment->GetMin() < p_max) {
433 if (p_max < segment->GetMax()) {
434 p_max = segment->GetMax();
435 }
436
437 b = a;
438 b.Next();
439 a.Destroy();
440
441 if (!b.Current(segment)) {
442 break;
443 }
444
445 a = b;
446 }
447
448 if (a.HasMatch()) {
449 MxSegment* copy = new MxSegment(p_min, p_max);
450 a.Prepend(copy);
451 }
452 else {
453 MxSegment* copy = new MxSegment(p_min, p_max);
454 m_segList->Append(copy);
455 }
456 }
457 else {
458 MxSegment* copy = new MxSegment(p_min, p_max);
459 m_segList->Append(copy);
460 }
461}
462
463// FUNCTION: LEGO1 0x100c55d0
465{
466 MxSpan* clone = new MxSpan(m_min, m_max);
467
469 MxSegment* segment;
470
471 while (cursor.Next(segment)) {
472 clone->m_segList->Append(segment->Clone());
473 }
474
475 return clone;
476}
477
478// FUNCTION: LEGO1 0x100c57b0
479// FUNCTION: BETA10 0x1014aa46
481{
483 MxSegment* segment;
484
485 while (cursor.Next(segment)) {
486 if (p_rect.GetRight() <= segment->GetMin()) {
487 return FALSE;
488 }
489
490 if (segment->GetMax() > p_rect.GetLeft()) {
491 return TRUE;
492 }
493 }
494
495 return FALSE;
496}
MxBool Next()
[AI]
MxBool Prev()
[AI]
void Prepend(T p_newobj)
[AI]
MxBool Head()
[AI]
Definition: mxlist.h:252
MxBool Last(T &p_obj)
[AI]
MxBool Tail()
[AI]
Definition: mxlist.h:261
MxBool Current(T &p_obj)
[AI]
void Reset()
[AI]
Definition: mxlist.h:269
MxBool HasMatch()
[AI]
Definition: mxlist.h:242
MxBool First(T &p_obj)
[AI]
void Destroy()
[AI]
void DeleteAll()
[AI]
void Append(T p_obj)
[AI]
Definition: mxlist.h:100
[AI] Rectangle using 32-bit signed integer coordinates.
Definition: mxgeometry.h:706
void SetLeft(T p_left)
[AI] Set the left edge.
Definition: mxgeometry.h:226
MxBool Empty() const
[AI] Returns whether the rectangle is empty or not.
Definition: mxgeometry.h:284
T GetTop() const
[AI] Get the top edge.
Definition: mxgeometry.h:231
MxBool Intersects(const MxRect &p_r) const
[AI] Returns whether this rectangle intersects another.
Definition: mxgeometry.h:299
void SetBottom(T p_bottom)
[AI] Set the bottom edge.
Definition: mxgeometry.h:256
T GetRight() const
[AI] Get the right edge.
Definition: mxgeometry.h:241
T GetLeft() const
[AI] Get the left edge.
Definition: mxgeometry.h:221
void SetTop(T p_top)
[AI] Set the top edge.
Definition: mxgeometry.h:236
T GetBottom() const
[AI] Get the bottom edge.
Definition: mxgeometry.h:251
void SetRight(T p_right)
[AI] Set the right edge.
Definition: mxgeometry.h:246
[AI] Cursor object suitable for traversing all rectangles covered by an MxRegion.
Definition: mxregion.h:389
void PrevSpan(MxRect32 &p_rect)
[AI] Step to the previous span (reverse traversal) intersecting p_rect.
Definition: mxregion.cpp:365
virtual void Reset()
[AI] Resets the cursor(s) to the initial (uninitialized) state.
Definition: mxregion.cpp:295
virtual MxRect32 * Prev()
[AI] Steps backward to and returns the previous rectangle in region sequence.
Definition: mxregion.cpp:204
void SetRect(MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom)
[AI] Initializes or updates m_rect with the specified coordinates.
Definition: mxregion.cpp:321
MxRegion * m_region
[AI] The region being traversed. [AI]
Definition: mxregion.h:391
MxSegmentListCursor * m_segListCursor
[AI] Cursor for the current segment list. [AI]
Definition: mxregion.h:394
virtual MxRect32 * Head()
[AI] Seeks to and returns the first (topmost, leftmost) rectangle covered by the region.
Definition: mxregion.cpp:137
void CreateSegmentListCursor(MxSegmentList *p_segList)
[AI] Allocates a segment list cursor for the given segment list, replacing any previous segment curso...
Definition: mxregion.cpp:311
MxSpanListCursor * m_spanListCursor
[AI] Cursor for moving through the span list. [AI]
Definition: mxregion.h:393
MxRect32 * m_rect
[AI] Current rectangle being referenced. [AI]
Definition: mxregion.h:392
void NextSpan(MxRect32 &p_rect)
[AI] Step to the next span which overlaps p_rect (for filtered/region-clip traversal).
Definition: mxregion.cpp:334
~MxRegionCursor() override
[AI] Destructor; releases ownership of current rectangle and cursors.
Definition: mxregion.cpp:121
virtual MxRect32 * Next()
[AI] Advances to and returns the next rectangle in region sequence.
Definition: mxregion.cpp:179
MxRegionCursor(MxRegion *p_region)
[AI] Constructs a traversal cursor for the specified region.
Definition: mxregion.cpp:112
virtual MxRect32 * Tail()
[AI] Seeks to and returns the last (bottommost, rightmost) rectangle covered by the region.
Definition: mxregion.cpp:158
[AI] Represents a 2D region as a set of vertical spans each containing one or more horizontal segment...
Definition: mxregion.h:327
virtual void Reset()
[AI] Removes all spans and resets the bounding rectangle to an empty state.
Definition: mxregion.cpp:27
MxSpanList * m_spanList
[AI] List of vertical spans for the region. [AI]
Definition: mxregion.h:329
virtual void AddRect(MxRect32 &p_rect)
[AI] Adds a rectangle to this region, merging or splitting spans and segments as necessary.
Definition: mxregion.cpp:35
~MxRegion() override
[AI] Destructor; destroys all spans and contained segments.
Definition: mxregion.cpp:20
virtual MxBool Intersects(MxRect32 &p_rect)
[AI] Checks if this region intersects with a given rectangle (any overlap between the region's covere...
Definition: mxregion.cpp:88
MxRect32 m_boundingRect
[AI] Cached bounding rectangle for the whole region. [AI]
Definition: mxregion.h:330
[AI] Cursor for traversing an MxSegmentList; allows sequential access through the segments.
Definition: mxregion.h:127
[AI] List container for segments; stores pointers to MxSegment objects and may take ownership dependi...
Definition: mxregion.h:102
[AI] Represents a 1D segment defined by a minimum and maximum integer value.
Definition: mxregion.h:13
MxBool IntersectsH(MxRect32 &p_rect)
[AI] Determines if this segment horizontally intersects a given rectangle, interpreted as an interval...
Definition: mxregion.h:67
MxSegment * Clone()
[AI] Creates a copy of the current segment.
Definition: mxregion.h:46
MxS32 GetMin()
[AI] Returns the lower boundary of the segment (inclusive).
Definition: mxregion.h:34
MxS32 GetMax()
[AI] Returns the upper boundary of the segment (exclusive).
Definition: mxregion.h:40
[AI] Cursor for traversing an MxSpanList, to sequentially access all spans in the list.
Definition: mxregion.h:312
[AI] List container for spans; holds MxSpan pointers and may automatically destroy them.
Definition: mxregion.h:282
[AI] Represents a vertical span—a 1D range plus a set of contained horizontal segments,...
Definition: mxregion.h:141
MxS32 m_max
[AI] Upper vertical boundary (usually 'bottom'). [AI]
Definition: mxregion.h:144
MxS32 GetMax()
[AI] Returns the vertical upper boundary of the span.
Definition: mxregion.h:180
MxS32 GetMin()
[AI] Returns the vertical lower boundary of the span.
Definition: mxregion.h:169
MxBool IntersectsH(MxRect32 &p_rect)
[AI] Checks if any segment in this span horizontally overlaps with the given rectangle.
Definition: mxregion.cpp:480
void AddSegment(MxS32 p_min, MxS32 p_max)
[AI] Adds a horizontal segment to this span, merging with adjacent segments if required to maintain c...
Definition: mxregion.cpp:417
void SetMin(MxS32 p_min)
[AI] Sets the vertical lower boundary of the span.
Definition: mxregion.h:175
void SetMax(MxS32 p_max)
[AI] Sets the vertical upper boundary of the span.
Definition: mxregion.h:186
MxSegmentList * m_segList
[AI] List of horizontal segments covered by this vertical span. [AI]
Definition: mxregion.h:145
MxSpan * Clone()
[AI] Deep copies this span, including all its attached segments.
Definition: mxregion.cpp:464
MxBool IntersectsV(MxRect32 &p_rect)
[AI] Check if this span vertically intersects a rectangle (vertical ranges overlap).
Definition: mxregion.h:225
MxSpan(MxS32 p_min, MxS32 p_max)
[AI] Constructs a span along the vertical axis with specified bounds.
Definition: mxregion.cpp:396
MxS32 m_min
[AI] Lower vertical boundary (usually 'top'). [AI]
Definition: mxregion.h:143
#define TRUE
Definition: d3drmdef.h:28
#define FALSE
Definition: d3drmdef.h:27
#define DECOMP_SIZE_ASSERT(T, S)
Definition: decomp.h:19
#define NULL
[AI] Null pointer value (C/C++ semantics).
Definition: legotypes.h:26
MxU8 MxBool
[AI]
Definition: mxtypes.h:124
signed int MxS32
[AI]
Definition: mxtypes.h:38