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{
12 namespace math
13 {
15 : m_width {0}
16 , m_height {0}
17 {
18 }
19
21 {
22 m_free_rects.clear();
23 }
24
25 void RectPack::init(const int width, const int height) noexcept
26 {
27 m_width = width;
28 m_height = height;
29
30 m_free_rects.emplace_back(sf::IntRect({0, 0}, {m_width, m_height}));
31 }
32
33 std::optional<sf::IntRect> RectPack::pack(const int width, const int height) noexcept
34 {
35 // Result.
36 std::optional<sf::IntRect> result = std::nullopt;
37
38 // Go over each space in the rectangle, in reverse order (i.e. smallest -> largest).
39 for (auto rit = m_free_rects.rbegin(); rit != m_free_rects.rend();)
40 {
41 auto& space = *rit;
42
43 // Check if rect can fit into space.
44 if (width <= space.size.x && height <= space.size.y)
45 {
46 // Make the packed area rectangle.
47 result = std::make_optional<sf::IntRect>(sf::IntRect({space.position.x, space.position.y}, {width, height}));
48
49 // Check to see if shape fills completely.
50 if (width == space.size.x && height == space.size.y)
51 {
52 // Destroy since not free space anymore.
53 std::advance(rit, 1);
54 m_free_rects.erase(rit.base());
55 }
56 else if (width == space.size.x)
57 {
58 // If just width fits, shrink new space.
59 space.position.y += height;
60 space.size.y -= height;
61 }
62 else if (height == space.size.y)
63 {
64 // Same as width, for height.
65 space.position.x += width;
66 space.size.x -= width;
67 }
68 else
69 {
70 // Otherwise, split up existing space.
71 m_free_rects.emplace_back(sf::IntRect({space.position.x + width, space.position.y}, {space.size.x - width, height}));
72
73 space.position.y += height;
74 space.size.y -= height;
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(sf::IntRect({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<sf::IntRect>& RectPack::get_free_space() const noexcept
107 {
108 return m_free_rects;
109 }
110 } // namespace math
111} // namespace galaxy
void init(const int width, const int height) noexcept
Set starting width and height of rectangle.
Definition RectPack.cpp:25
std::optional< sf::IntRect > pack(const int width, const int height) noexcept
Pack a rectangle into the master rectangle.
Definition RectPack.cpp:33
int get_width() const noexcept
Get total width.
Definition RectPack.cpp:96
int m_width
The starting width of the rectangle.
Definition RectPack.hpp:91
~RectPack() noexcept
Destructor.
Definition RectPack.cpp:20
void clear() noexcept
Clear all data.
Definition RectPack.cpp:90
std::vector< sf::IntRect > m_free_rects
Free space in master rectangle.
Definition RectPack.hpp:101
int m_height
The starting width of the rectangle.
Definition RectPack.hpp:96
RectPack() noexcept
Constructor.
Definition RectPack.cpp:14
const std::vector< sf::IntRect > & get_free_space() const noexcept
Get free rectangles.
Definition RectPack.cpp:106
int get_height() const noexcept
Get total height.
Definition RectPack.cpp:101
Timer.hpp galaxy.
Definition Async.hpp:17