refactor tile packing, cut tools file pathing
This commit is contained in:
parent
8017fe37e5
commit
d087aaae73
4 changed files with 284 additions and 218 deletions
100
src/kiri/pack.js
100
src/kiri/pack.js
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue