galaxy 1.0.0
Real-Time C++23 Game Programming Framework. Built on data-driven design principles and agile software engineering.
Loading...
Searching...
No Matches
RectPack.cpp
Go to the documentation of this file.
1
7
8#include "RectPack.hpp"
9
10namespace galaxy
11{
13 : m_width {0}
14 , m_height {0}
15 {
16 }
17
19 {
20 m_free_rects.clear();
21 }
22
23 void RectPack::init(const int width, const int height) noexcept
24 {
25 m_width = width;
26 m_height = height;
27
28 m_free_rects.emplace_back(0, 0, m_width, m_height);
29 }
30
31 std::optional<iRect> RectPack::pack(const int width, const int height)
32 {
33 // Result.
34 std::optional<iRect> result = std::nullopt;
35
36 // Go over each space in the rectangle, in reverse order (i.e. smallest -> largest).
37 for (auto rit = m_free_rects.rbegin(); rit != m_free_rects.rend();)
38 {
39 auto& space = *rit;
40
41 // Check if rect can fit into space.
42 if (width <= space.width && height <= space.height)
43 {
44 // Make the packed area rectangle.
45 result = std::make_optional<iRect>(space.x, space.y, width, height);
46
47 // Check to see if shape fills completely.
48 if (width == space.width && height == space.height)
49 {
50 // Destroy since not free space anymore.
51 std::advance(rit, 1);
52 m_free_rects.erase(rit.base());
53 }
54 else if (width == space.width)
55 {
56 // If just width fits, shrink new space.
57 space.y += height;
58 space.height -= height;
59 }
60 else if (height == space.height)
61 {
62 // Same as width, for height.
63 space.x += width;
64 space.width -= width;
65 }
66 else
67 {
68 // Otherwise, split up existing space.
69 iRect temp = {space.x + width, space.y, space.width - width, height};
70
71 space.y += height;
72 space.height -= height;
73
74 m_free_rects.emplace_back(temp);
75 }
76
77 // If it can fit, no longer need to keep iterating through.
78 break;
79 }
80 else
81 {
82 // Try next space.
83 ++rit;
84 }
85 }
86
87 return result;
88 }
89
90 void RectPack::clear() noexcept
91 {
92 m_free_rects.clear();
93 m_free_rects.emplace_back(0, 0, m_width, m_height);
94 }
95
96 int RectPack::get_width() const noexcept
97 {
98 return m_width;
99 }
100
101 int RectPack::get_height() const noexcept
102 {
103 return m_height;
104 }
105
106 const std::vector<iRect>& RectPack::get_free_space() const noexcept
107 {
108 return m_free_rects;
109 }
110} // namespace galaxy
int m_width
The starting width of the rectangle.
Definition RectPack.hpp:89
const std::vector< iRect > & get_free_space() const noexcept
Get free rectangles.
Definition RectPack.cpp:106
std::optional< iRect > pack(const int width, const int height)
Pack a rectangle into the master rectangle.
Definition RectPack.cpp:31
RectPack() noexcept
Constructor.
Definition RectPack.cpp:12
int m_height
The starting width of the rectangle.
Definition RectPack.hpp:94
void clear() noexcept
Clear all data.
Definition RectPack.cpp:90
int get_height() const noexcept
Get total height.
Definition RectPack.cpp:101
void init(const int width, const int height) noexcept
Set starting width and height of rectangle.
Definition RectPack.cpp:23
int get_width() const noexcept
Get total width.
Definition RectPack.cpp:96
~RectPack() noexcept
Destructor.
Definition RectPack.cpp:18
std::vector< iRect > m_free_rects
Free space in master rectangle.
Definition RectPack.hpp:99
Represents a rectangle object.
Definition Rect.hpp:26
Type y
Y position.
Definition Rect.hpp:151
Timer.hpp galaxy.
Definition Timer.cpp:18