MCPcopy Create free account
hub / github.com/DavidColson/Polybox / SkylinePackRects

Method SkylinePackRects

source/rect_packing.cpp:102–190  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

100// ***********************************************************************
101
102void Packing::SkylinePackRects(Arena* pScratchMem, ResizableArray<Rect>& rects, i32 width, i32 height) {
103 for (i64 i = 0; i < rects.count; i++) {
104 rects[i].ordering = (int)i;
105 }
106
107 // Sort by a heuristic
108 Sort(rects.pData, rects.count, SortByHeight());
109
110 i32 maxX = 0;
111 i32 maxY = 0;
112 i32 totalArea = 0;
113
114 ResizableArray<SkylineNode> nodes(pScratchMem);
115
116 nodes.PushBack({ 0, 0, width });
117
118 for (Rect& rect : rects) {
119 i32 bestHeight = height;
120 i32 bestWidth = width;
121 i32 bestNode = -1;
122 i32 bestX, bestY;
123 // We're going to search for the best location for this rect along the skyline
124 for (i64 i = 0; i < nodes.count; i++) {
125 SkylineNode& node = nodes[i];
126 i32 highestY = CanRectFit(nodes, (i32)i, rect.w, rect.h, width, height);
127 if (highestY != -1) {
128 // Settling a tie here on best height by checking lowest width we can use up
129 if (highestY + rect.h < bestHeight || (highestY + rect.h == bestHeight && node.width < bestWidth)) {
130 bestNode = (int)i;
131 bestWidth = node.width;
132 bestHeight = highestY + rect.h;
133 bestX = node.x;
134 bestY = highestY;
135 }
136 }
137 }
138
139 if (bestNode == -1)
140 continue; // We failed
141
142 // Add the actual rect, changing the skyline
143
144 // First add the new node
145 SkylineNode newNode;
146 newNode.width = rect.w;
147 newNode.x = bestX;
148 newNode.y = bestY + rect.h;
149 nodes.Insert(bestNode, newNode);
150
151 // Now we have to find all the nodes underneath that new skyline level and remove them
152 for (int i = bestNode + 1; i < (int)nodes.count; i++) {
153 SkylineNode& node = nodes[i];
154 SkylineNode& prevNode = nodes[i - 1];
155 // Check to see if the current node is underneath the previous node
156 // Remember that i starts as the first node after we inserted, so the previous node is the one we inserted
157 if (node.x < prevNode.x + prevNode.width) {
158 // Draw a picture of this
159 i32 amountToShrink = (prevNode.x + prevNode.width) - node.x;

Callers

nothing calls this directly

Calls 3

SortByHeightClass · 0.85
CanRectFitFunction · 0.85
SortToOriginalOrderClass · 0.85

Tested by

no test coverage detected