refactor tile packing, cut tools file pathing

This commit is contained in:
Stewart Allen 2024-06-13 19:00:04 -04:00
commit d087aaae73
4 changed files with 284 additions and 218 deletions

View file

@ -13,6 +13,15 @@ const { kiri } = root;
class Packer {
constructor(w, h, spacing, opt = {}) {
this.w = w;
this.h = h;
this.spacing = spacing;
this.opt = opt;
this.init();
}
init() {
const { w, h, spacing, opt } = this;
this.root = { x: 0, y: 0, w: w, h: h };
this.max = { w: 0, h: 0 };
this.packed = false;
@ -21,23 +30,61 @@ class Packer {
this.pad = this.spacing / 2;
}
get size() {
return { w: this.w, h: this. h };
}
resize(w, h) {
this.w = w;
this.h = h;
return this;
}
rescale(wm, hm) {
this.w *= wm;
this.h *= hm;
return this;
}
pack(blocks, onretry) {
for (;;) {
let simple = this.opt.simple;
this.fit(blocks, simple);
if (!this.packed && onretry && onretry(this)) {
this.init();
continue;
}
return this;
}
}
// array of blocks/tiles with {w,h} properties
simple(blocks) {
let n = 0, block, x = 0, y = 0, mh = 0, maxx = 0, maxy = 0;
let spacing = blocks.length > 1 ? this.spacing : 0;
while (n < blocks.length) {
block = blocks[n++];
fit(blocks, simple) {
if (simple) {
return this.#fit_simple(blocks);
} else {
return this.#fit_split(blocks);
}
}
// array of blocks/tiles with {w,h} properties
#fit_simple(blocks) {
let x = 0, y = 0, mh = 0, maxx = 0, maxy = 0;
let spacing = this.spacing;
for (let block of blocks) {
block.fit = { x, y };
this.max.w = Math.max(this.max.w, x + block.w);
this.max.h = Math.max(this.max.h, y + block.h);
maxx = Math.max(maxx, x);
maxy = Math.max(maxy, y);
mh = Math.max(mh, block.h);
x += block.w + spacing;
x += block.w;
if (x > this.root.w) {
x = 0;
y = y + mh + spacing;
mh = 0;
} else {
x += spacing;
}
if (y > this.root.h) {
return this;
@ -57,18 +104,14 @@ class Packer {
return this;
}
fit(blocks, simple) {
if (simple) {
return this.simple(blocks);
}
let n = 0, node, block, w, h;
let spacing = blocks.length > 1 ? this.spacing : 0;
while (n < blocks.length) {
block = blocks[n++];
w = block.w + spacing;
h = block.h + spacing;
if (node = this.findNode(this.root, w, h)) {
block.fit = this.splitNode(node, w, h);
// array of blocks/tiles with {w,h} properties
#fit_split(blocks) {
let node, w, h;
for (let block of blocks) {
w = block.w;
h = block.h;
if (node = this.#findNode(this.root, w, h)) {
block.fit = this.#splitNode(node, w, h);
} else {
return this;
}
@ -77,9 +120,9 @@ class Packer {
return this;
}
findNode(root, w, h) {
#findNode(root, w, h) {
if (root.used) {
return this.findNode(root.right, w, h) || this.findNode(root.down, w, h);
return this.#findNode(root.right, w, h) || this.#findNode(root.down, w, h);
} else if (w <= root.w && h <= root.h) {
return root;
} else {
@ -87,10 +130,21 @@ class Packer {
}
}
splitNode(node, w, h) {
#splitNode(node, w, h) {
let spacing = this.spacing;
node.used = true;
node.down = { x: node.x, y: node.y + h, w: node.w, h: node.h - h };
node.right = { x: node.x + w, y: node.y, w: node.w - w, h: h };
node.down = {
x: node.x,
y: node.y + h + spacing,
w: node.w,
h: node.h - h
};
node.right = {
x: node.x + w + spacing,
y: node.y,
w: node.w - w,
h: h
};
this.max.w = Math.max(this.max.w, node.x + w);
this.max.h = Math.max(this.max.h, node.y + h);
return node;

View file

@ -735,8 +735,8 @@ function platformLayout() {
for (i = 0; i < c.length; i++) {
m = c[i];
m.fit.x += m.w / 2 + p.pad;
m.fit.y += m.h / 2 + p.pad;
m.fit.x += m.w / 2;
m.fit.y += m.h / 2;
m.move(p.max.w / 2 - m.fit.x, p.max.h / 2 - m.fit.y, 0, true);
}
}