Clear unused texture space feature

This commit is contained in:
JannisX11 2023-05-28 15:13:00 +02:00
parent 4260d6bb58
commit 15a08bd642
5 changed files with 67 additions and 4 deletions

View File

@ -311,6 +311,7 @@ const MenuBar = {
'adjust_curves',
'_',
'limit_to_palette',
'clear_unused_texture_space',
'_',
'flip_texture_x',
'flip_texture_y',

View File

@ -613,6 +613,65 @@ BARS.defineActions(function() {
Undo.finishEdit('Limit texture to palette')
}
})
new Action('clear_unused_texture_space', {
icon: 'cleaning_services',
category: 'textures',
condition: {modes: ['paint'], features: ['edit_mode'], method: () => Texture.all.length},
click() {
let textures = getTextures();
Undo.initEdit({textures, bitmap: true});
textures.forEach(texture => {
if (texture.frameCount > 1) {
Blockbench.showQuickMessage('This feature does not work on animated textures at the moment');
return;
}
texture.edit((canvas) => {
// todo: flipbook animation support
let ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
Outliner.elements.forEach(el => {
if (el instanceof Mesh) {
for (var fkey in el.faces) {
var face = el.faces[fkey];
if (face.vertices.length <= 2 || face.getTexture() !== texture) continue;
let matrix = face.getOccupationMatrix(true, [0, 0]);
for (let x in matrix) {
for (let y in matrix[x]) {
if (!matrix[x][y]) continue;
x = parseInt(x); y = parseInt(y);
ctx.rect(x, y, 1, 1);
}
}
}
} else if (el instanceof Cube) {
let factor_x = texture.width / Project.texture_width;
let factor_y = texture.height / Project.texture_height;
for (var fkey in el.faces) {
var face = el.faces[fkey];
if (face.getTexture() !== texture) continue;
let rect = face.getBoundingRect();
let canvasRect = [
Math.floor(rect.ax * factor_x),
Math.floor(rect.ay * factor_y),
Math.ceil(rect.bx * factor_x) - Math.floor(rect.ax * factor_x),
Math.ceil(rect.by * factor_y) - Math.floor(rect.ay * factor_y),
]
ctx.rect(...canvasRect);
}
}
})
ctx.clip();
ctx.drawImage(texture.img, 0, 0);
}, {no_undo: true});
})
Undo.finishEdit('Clear unused texture space')
}
})
// Transform
new Action('flip_texture_x', {

View File

@ -1554,6 +1554,7 @@ class Texture {
'adjust_curves',
'_',
'limit_to_palette',
'clear_unused_texture_space',
'_',
'flip_texture_x',
'flip_texture_y',

View File

@ -1381,6 +1381,8 @@
"action.adjust_curves.desc": "Adjust the brightness curves of the selected texture",
"action.limit_to_palette": "Limit to Palette",
"action.limit_to_palette.desc": "Limits the colors of the texture to those in the currently loaded palette",
"action.clear_unused_texture_space": "Clear Unused Texture Space",
"action.clear_unused_texture_space.desc": "Clear parts of the texture that are not UV-mapped to any elements",
"action.flip_texture_x": "Flip Texture Horizontally",
"action.flip_texture_y": "Flip Texture Vertically",
"action.rotate_texture_cw": "Rotate Texture Clockwise",

View File

@ -48,10 +48,10 @@ class CanvasFrame {
}
this.ctx.drawImage(img, 0, 0)
}
loadFromCanvas(img) {
this.canvas.width = image.naturalWidth;
this.canvas.height = image.naturalHeight;
this.ctx.drawImage(img, 0, 0)
loadFromCanvas(canvas) {
this.canvas.width = canvas.width;
this.canvas.height = canvas.height;
this.ctx.drawImage(canvas, 0, 0)
}
autoCrop() {
// Based on code by remy, licensed under MIT