Pixel-Composer/scripts/pack_skyline/pack_skyline.gml

59 lines
1.6 KiB
Text
Raw Normal View History

2023-03-19 09:17:39 +01:00
function Strip(x, y, w, h) constructor {
self.x = x;
self.y = y;
self.w = w;
self.h = h;
}
function sprite_pack_skyline(rectangles, width, height) {
var maxw = 0;
var maxh = 0;
array_sort(rectangles, function(a, b) {
return b.w - a.w;
});
var skyline = [ new Strip(0, 0, width, height) ];
var packed = [];
for (var i = 0; i < array_length(rectangles); i++) {
var rect = rectangles[i];
var bestStrip = noone;
var bestWasted = width * height;
for (var j = 0; j < array_length(skyline); j++) {
var strip = skyline[j];
if (strip.w >= rect.w && strip.h >= rect.h) {
var wasted = strip.w * strip.h;
if (wasted <= bestWasted) {
bestStrip = strip;
bestWasted = wasted;
}
}
}
if (bestStrip == noone) continue;
rect.x = bestStrip.x;
rect.y = bestStrip.y;
array_push(packed, rect);
if (bestStrip.w > rect.w)
array_push(skyline, new Strip(bestStrip.x + rect.w, bestStrip.y, bestStrip.w - rect.w, bestStrip.h));
if (bestStrip.h > rect.h)
array_push(skyline, new Strip(bestStrip.x, bestStrip.y + rect.h, rect.w, bestStrip.h - rect.h));
array_remove(skyline, bestStrip);
array_sort(skyline, function(a, b) {
return a.x - b.x;
});
maxw = max(maxw, rect.x + rect.w);
maxh = max(maxh, rect.y + rect.h);
}
return [ new Rectangle(0, 0, maxw, maxh), packed ];
}