MCPcopy Create free account
hub / github.com/FlaxEngine/FlaxEngine / Insert

Method Insert

Source/Engine/Utilities/RectPack.h:157–215  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

155 /// <returns>The node that contains inserted an item or null if failed to find a free space.</returns>
156 template<class... Args>
157 NodeType* Insert(Size width, Size height, Args&&... args)
158 {
159 NodeType* result = nullptr;
160 const Size paddedWidth = width + BordersPadding;
161 const Size paddedHeight = height + BordersPadding;
162
163 // Search free nodes from back to front and find the one that fits requested item size
164 // TODO: FreeNodes are sorted so use Binary Search to quickly find the first tile that might have enough space for insert
165 for (int32 i = FreeNodes.Count() - 1; i >= 0; i--)
166 {
167 NodeType* freeNode = FreeNodes.Get()[i];
168 if (paddedWidth > freeNode->Width || paddedHeight > freeNode->Height)
169 {
170 // Not enough space
171 continue;
172 }
173
174 // Check if there will be some remaining space left in this node
175 if (freeNode->Width != width || freeNode->Height != height)
176 {
177 // Subdivide this node into up to 2 additional nodes
178 const Size remainingWidth = freeNode->Width - paddedWidth;
179 const Size remainingHeight = freeNode->Height - paddedHeight;
180
181 // Split the remaining area around this node into two children
182 SizeRect bigger, smaller;
183 if (remainingHeight <= remainingWidth)
184 {
185 // Split vertically
186 smaller = SizeRect(freeNode->X, freeNode->Y + paddedHeight, width, remainingHeight);
187 bigger = SizeRect(freeNode->X + paddedWidth, freeNode->Y, remainingWidth, freeNode->Height);
188 }
189 else
190 {
191 // Split horizontally
192 smaller = SizeRect(freeNode->X + paddedWidth, freeNode->Y, remainingWidth, height);
193 bigger = SizeRect(freeNode->X, freeNode->Y + paddedHeight, freeNode->Width, remainingHeight);
194 }
195 if (smaller.W * smaller.H > bigger.W * bigger.H)
196 Swap(bigger, smaller);
197 if (bigger.W * bigger.H > BordersPadding)
198 AddFreeNode(Nodes.Add(NodeType(bigger.X, bigger.Y, bigger.W, bigger.H)));
199 if (smaller.W * smaller.H > BordersPadding)
200 AddFreeNode(Nodes.Add(NodeType(smaller.X, smaller.Y, smaller.W, smaller.H)));
201
202 // Shrink to the actual area
203 freeNode->Width = width;
204 freeNode->Height = height;
205 }
206
207 // Insert into this node
208 result = freeNode;
209 FreeNodes.RemoveAtKeepOrder(i);
210 result->OnInsert(Forward<Args>(args)...);
211 break;
212 }
213
214 return result;

Callers 3

AddFreeNodeMethod · 0.45
InsertFunction · 0.45

Calls 7

SizeRectClass · 0.85
RemoveAtKeepOrderMethod · 0.80
SwapFunction · 0.50
CountMethod · 0.45
GetMethod · 0.45
AddMethod · 0.45
OnInsertMethod · 0.45

Tested by

no test coverage detected