mirror of
https://github.com/JannisX11/blockbench.git
synced 2024-11-27 04:21:46 +08:00
Improve smooth brush stroke
This commit is contained in:
parent
e1e1cd3dd3
commit
28dba208d9
@ -130,11 +130,12 @@ const Painter = {
|
||||
Blockbench.showQuickMessage('message.untextured')
|
||||
return;
|
||||
}
|
||||
let offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brush?.offset_even_radius ? 0.5 : 0;
|
||||
var x = data.intersects[0].uv.x * texture.img.naturalWidth + offset;
|
||||
var y = (1-data.intersects[0].uv.y) * texture.img.naturalHeight + offset;
|
||||
if (!Toolbox.selected.brush || Toolbox.selected.brush.floor_coordinates !== false) {
|
||||
x = Math.floor(x); y = Math.floor(y);
|
||||
var x = data.intersects[0].uv.x * texture.img.naturalWidth;
|
||||
var y = (1-data.intersects[0].uv.y) * texture.img.naturalHeight;
|
||||
if (!Toolbox.selected.brush || Condition(Toolbox.selected.brush.floor_coordinates)) {
|
||||
let offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brush?.offset_even_radius ? 0.5 : 0;
|
||||
x = Math.floor(x + offset);
|
||||
y = Math.floor(y + offset);
|
||||
}
|
||||
Painter.startPaintTool(texture, x, y, data.element.faces[data.face].uv, e, data)
|
||||
|
||||
@ -150,9 +151,13 @@ const Painter = {
|
||||
var texture = data.element.faces[data.face].getTexture()
|
||||
if (texture) {
|
||||
var x, y, new_face;
|
||||
let offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brush?.offset_even_radius ? 0.5 : 0;
|
||||
x = Math.floor( data.intersects[0].uv.x * texture.img.naturalWidth + offset );
|
||||
y = Math.floor( (1-data.intersects[0].uv.y) * texture.img.naturalHeight + offset );
|
||||
x = data.intersects[0].uv.x * texture.img.naturalWidth;
|
||||
y = (1-data.intersects[0].uv.y) * texture.img.naturalHeight;
|
||||
if (!Toolbox.selected.brush || Condition(Toolbox.selected.brush.floor_coordinates)) {
|
||||
let offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brush?.offset_even_radius ? 0.5 : 0;
|
||||
x = Math.floor(x + offset);
|
||||
y = Math.floor(y + offset);
|
||||
}
|
||||
if (texture.img.naturalWidth + texture.img.naturalHeight == 0) return;
|
||||
|
||||
if (x === Painter.current.x && y === Painter.current.y) {
|
||||
@ -604,7 +609,7 @@ const Painter = {
|
||||
point_on_uv[0] = Math.min(face.uv[0], face.uv[0+2]) * uvFactorX + point_on_uv[0];
|
||||
}
|
||||
let mirror_y = symmetry_axes[0] != symmetry_axes[2];
|
||||
if (face.uv[1] > face.uv[1+2] == uvTag[1] > uvTag[1+2]) {
|
||||
if (face.uv[1] > face.uv[1+2] == uvTag[1] > uvTag[1+2] == mirror_y) {
|
||||
point_on_uv[1] = Math.min(face.uv[1], face.uv[1+2]) * uvFactorY + point_on_uv[1];
|
||||
} else {
|
||||
point_on_uv[1] = Math.max(face.uv[1], face.uv[1+2]) * uvFactorY - point_on_uv[1] - 1;
|
||||
@ -729,8 +734,8 @@ const Painter = {
|
||||
var i = Math.min(interval, length);
|
||||
var x, y;
|
||||
while (i <= length) {
|
||||
x = Math.round(start_x + diff_x / length * i)
|
||||
y = Math.round(start_y + diff_y / length * i)
|
||||
x = length ? (start_x + diff_x / length * i) : end_x;
|
||||
y = length ? (start_y + diff_y / length * i) : end_y;
|
||||
Painter.useBrushlike(texture, x, y, event, uv, i < length-1);
|
||||
i += interval;
|
||||
}
|
||||
@ -1185,7 +1190,7 @@ const Painter = {
|
||||
},
|
||||
editCircle(ctx, x, y, r, s, editPx) {
|
||||
r = Math.round(r+1)/2
|
||||
Painter.scanCanvas(ctx, x-Math.ceil(r)-2, y-Math.ceil(r)-2, 2*r+3, 2*r+3, function (px, py, pixel) {
|
||||
Painter.scanCanvas(ctx, Math.floor(x)-Math.ceil(r)-2, Math.floor(y)-Math.ceil(r)-2, 2*r+3, 2*r+3, function (px, py, pixel) {
|
||||
if (
|
||||
settings.paint_side_restrict.value &&
|
||||
Painter.editing_area &&
|
||||
@ -1200,10 +1205,18 @@ const Painter = {
|
||||
return;
|
||||
}
|
||||
|
||||
px -= x - r%1;
|
||||
py -= y - r%1;
|
||||
let v_px = px - x;
|
||||
let v_py = py - y;
|
||||
|
||||
var distance = Math.sqrt(px*px + py*py)
|
||||
if (x%1) {
|
||||
// Smooth
|
||||
v_px += 0.5; v_py += 0.5;
|
||||
} else if (r%1) {
|
||||
// Pixel Perfect
|
||||
v_px += 0.5; v_py += r%1;
|
||||
}
|
||||
|
||||
var distance = Math.sqrt(v_px*v_px + v_py*v_py)
|
||||
if (s*r != 0) {
|
||||
var pos_on_gradient = (distance-(1-s)*r) / (s*r)
|
||||
} else {
|
||||
@ -1221,7 +1234,7 @@ const Painter = {
|
||||
g: pixel[1],
|
||||
b: pixel[2],
|
||||
a: pixel[3]/255
|
||||
}, opacity, px+x, py+y)
|
||||
}, opacity, px, py)
|
||||
pixel[0] = result_color.r
|
||||
pixel[1] = result_color.g
|
||||
pixel[2] = result_color.b
|
||||
@ -1230,8 +1243,8 @@ const Painter = {
|
||||
});
|
||||
},
|
||||
editSquare(ctx, x, y, r, s, editPx) {
|
||||
r = Math.round(r+1)/2
|
||||
Painter.scanCanvas(ctx, x-Math.ceil(r)-2, y-Math.ceil(r)-2, 2*r+3, 2*r+3, function (px, py, pixel) {
|
||||
r = Math.round(r+1)/2;
|
||||
Painter.scanCanvas(ctx, Math.floor(x)-Math.ceil(r)-2, Math.floor(y)-Math.ceil(r)-2, 2*r+3, 2*r+3, function (px, py, pixel) {
|
||||
if (
|
||||
settings.paint_side_restrict.value &&
|
||||
Painter.editing_area &&
|
||||
@ -1246,10 +1259,18 @@ const Painter = {
|
||||
return;
|
||||
}
|
||||
|
||||
px -= x - r%1;
|
||||
py -= y - r%1;
|
||||
let v_px = px - x;
|
||||
let v_py = py - y;
|
||||
|
||||
var distance = Math.max(Math.abs(px), Math.abs(py));
|
||||
if (x%1) {
|
||||
// Smooth
|
||||
v_px += 0.5; v_py += 0.5;
|
||||
} else if (r%1) {
|
||||
// Pixel Perfect
|
||||
v_px += 0.5; v_py += r%1;
|
||||
}
|
||||
|
||||
var distance = Math.max(Math.abs(v_px), Math.abs(v_py));
|
||||
if (s*r != 0) {
|
||||
var pos_on_gradient = (distance-(1-s)*r) / (s*r)
|
||||
} else {
|
||||
@ -1264,7 +1285,7 @@ const Painter = {
|
||||
g: pixel[1],
|
||||
b: pixel[2],
|
||||
a: pixel[3]/255
|
||||
}, opacity, px+x, py+y)
|
||||
}, opacity, px, py)
|
||||
pixel[0] = result_color.r
|
||||
pixel[1] = result_color.g
|
||||
pixel[2] = result_color.b
|
||||
@ -1338,6 +1359,7 @@ BARS.defineActions(function() {
|
||||
softness: true,
|
||||
opacity: true,
|
||||
offset_even_radius: true,
|
||||
floor_coordinates: () => BarItems.slider_brush_softness.get() == 0,
|
||||
changePixel(px, py, pxcolor, local_opacity, {color, opacity, ctx, x, y, size, softness, texture, event}) {
|
||||
let blend_mode = BarItems.blend_mode.value;
|
||||
var a = opacity * local_opacity;
|
||||
@ -1526,7 +1548,7 @@ BARS.defineActions(function() {
|
||||
size: true,
|
||||
softness: true,
|
||||
opacity: true,
|
||||
offset_even_radius: true,
|
||||
floor_coordinates: () => BarItems.slider_brush_softness.get() == 0,
|
||||
changePixel(px, py, pxcolor, local_opacity, {opacity, ctx, x, y, size, softness, texture, event}) {
|
||||
if (Painter.lock_alpha) return pxcolor;
|
||||
|
||||
|
@ -74,7 +74,7 @@ const UVEditor = {
|
||||
let offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brush?.offset_even_radius ? 0.5 : 0;
|
||||
result.x = mouse_coords[0]/pixel_size*1 + offset;
|
||||
result.y = mouse_coords[1]/pixel_size*1 + offset;
|
||||
if (!Toolbox.selected.brush || Toolbox.selected.brush.floor_coordinates !== false) {
|
||||
if (!Toolbox.selected.brush || Condition(Toolbox.selected.brush.floor_coordinates)) {
|
||||
result.x = Math.floor(result.x);
|
||||
result.y = Math.floor(result.y);
|
||||
}
|
||||
@ -1920,9 +1920,13 @@ Interface.definePanels(function() {
|
||||
this.mouse_coords.x = Math.round(event.offsetX/pixel_size*1);
|
||||
this.mouse_coords.y = Math.round(event.offsetY/pixel_size*1);
|
||||
} else {
|
||||
let offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brush?.offset_even_radius ? 0.5 : 0;
|
||||
this.mouse_coords.x = Math.floor(event.offsetX/pixel_size*1 + offset);
|
||||
this.mouse_coords.y = Math.floor(event.offsetY/pixel_size*1 + offset);
|
||||
this.mouse_coords.x = event.offsetX/pixel_size*1;
|
||||
this.mouse_coords.y = event.offsetY/pixel_size*1;
|
||||
if (!Toolbox.selected.brush || Condition(Toolbox.selected.brush.floor_coordinates)) {
|
||||
let offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brush?.offset_even_radius ? 0.5 : 0;
|
||||
this.mouse_coords.x = Math.floor(this.mouse_coords.x + offset);
|
||||
this.mouse_coords.y = Math.floor(this.mouse_coords.y + offset);
|
||||
}
|
||||
}
|
||||
if (this.texture && this.texture.frameCount) {
|
||||
this.mouse_coords.y += (this.texture.height / this.texture.frameCount) * this.texture.currentFrame
|
||||
@ -2845,7 +2849,10 @@ Interface.definePanels(function() {
|
||||
if (Toolbox.selected.brush) {
|
||||
var pixel_size = this.inner_width / (this.texture ? this.texture.width : Project.texture_width);
|
||||
//pos
|
||||
let offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brush?.offset_even_radius ? 0 : 0.5;
|
||||
let offset = 0;
|
||||
if (!Toolbox.selected.brush || Condition(Toolbox.selected.brush.floor_coordinates)) {
|
||||
offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brush?.offset_even_radius ? 0 : 0.5;
|
||||
}
|
||||
let left = (this.mouse_coords.x + offset) * pixel_size;
|
||||
let top = (this.mouse_coords.y + offset) * pixel_size;
|
||||
//size
|
||||
@ -3056,7 +3063,7 @@ Interface.definePanels(function() {
|
||||
|
||||
<template v-else>
|
||||
<span v-if="copy_overlay.state == 'select'" style="color: var(--color-subtle_text);">{{ copy_overlay.width + ' ⨉ ' + copy_overlay.height }}</span>
|
||||
<span v-else style="color: var(--color-subtle_text);">{{ mouse_coords.x < 0 ? '-' : (mouse_coords.x + ', ' + mouse_coords.y) }}</span>
|
||||
<span v-else style="color: var(--color-subtle_text);">{{ mouse_coords.x < 0 ? '-' : (trimFloatNumber(mouse_coords.x, 1) + ', ' + trimFloatNumber(mouse_coords.y, 1)) }}</span>
|
||||
<span v-if="texture" class="uv_panel_texture_name" @click="selectTextureMenu($event)">{{ texture.name }}</span>
|
||||
<span style="color: var(--color-subtle_text);">{{ Math.round(this.zoom*100).toString() + '%' }}</span>
|
||||
</template>
|
||||
|
@ -224,9 +224,9 @@ Math.snapToValues = function(val, snap_points, epsilon = 12) {
|
||||
return val
|
||||
}
|
||||
}
|
||||
function trimFloatNumber(val) {
|
||||
function trimFloatNumber(val, max_digits = 4) {
|
||||
if (val == '') return val;
|
||||
var string = val.toFixed(4)
|
||||
var string = val.toFixed(max_digits)
|
||||
string = string.replace(/0+$/g, '').replace(/\.$/g, '')
|
||||
if (string == -0) return 0;
|
||||
return string;
|
||||
|
Loading…
Reference in New Issue
Block a user