Clone tool
This commit is contained in:
@@ -119,7 +119,7 @@ class MaterialBuilder {
|
||||
frag.add_uniform('float brushOpacity', '_brushOpacity');
|
||||
frag.add_uniform('float brushHardness', '_brushHardness');
|
||||
|
||||
if (UITrait.inst.brushType == 0 || UITrait.inst.brushType == 1 || decal) { // Draw / Erase
|
||||
if (UITrait.inst.brushType == 0 || UITrait.inst.brushType == 1 || decal || UITrait.inst.brushType == 8) { // Draw / Erase
|
||||
|
||||
#if (kha_opengl || kha_webgl)
|
||||
frag.write('if (sp.z > textureLod(paintdb, vec2(sp.x, 1.0 - bsp.y), 0).r) { discard; }');
|
||||
@@ -237,23 +237,55 @@ class MaterialBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
Cycles.parse_height_as_channel = true;
|
||||
var sout = Cycles.parse(UINodes.inst.canvas, con_paint, vert, frag, null, null, null, matcon);
|
||||
Cycles.parse_height_as_channel = false;
|
||||
var base = sout.out_basecol;
|
||||
var rough = sout.out_roughness;
|
||||
var met = sout.out_metallic;
|
||||
var occ = sout.out_occlusion;
|
||||
var nortan = Cycles.out_normaltan;
|
||||
var height = sout.out_height;
|
||||
var opac = sout.out_opacity;
|
||||
frag.write('vec3 basecol = $base;');
|
||||
frag.write('float roughness = $rough;');
|
||||
frag.write('float metallic = $met;');
|
||||
frag.write('float occlusion = $occ;');
|
||||
frag.write('vec3 nortan = $nortan;');
|
||||
frag.write('float height = $height;');
|
||||
frag.write('float opacity = $opac * brushOpacity;');
|
||||
var clone = UITrait.inst.brushType == 8;
|
||||
if (clone) {
|
||||
frag.add_uniform('sampler2D gbuffer2');
|
||||
frag.add_uniform('vec2 gbufferSize', '_gbufferSize');
|
||||
frag.add_uniform('vec2 cloneDelta', '_cloneDelta');
|
||||
#if (kha_opengl || kha_webgl)
|
||||
frag.write('vec2 texCoordInp = texelFetch(gbuffer2, ivec2((sp.x + cloneDelta.x) * gbufferSize.x, (1.0 - (sp.y + cloneDelta.y)) * gbufferSize.y), 0).ba;');
|
||||
#else
|
||||
frag.write('vec2 texCoordInp = texelFetch(gbuffer2, ivec2((sp.x + cloneDelta.x) * gbufferSize.x, (sp.y + cloneDelta.y) * gbufferSize.y), 0).ba;');
|
||||
#end
|
||||
frag.add_uniform('sampler2D texpaint_undo', '_texpaint_undo');
|
||||
frag.add_uniform('sampler2D texpaint_nor_undo', '_texpaint_nor_undo');
|
||||
frag.add_uniform('sampler2D texpaint_pack_undo', '_texpaint_pack_undo');
|
||||
frag.write('vec3 texpaint_pack_sample = textureLod(texpaint_pack_undo, texCoordInp, 0).rgb;');
|
||||
|
||||
var base = 'textureLod(texpaint_undo, texCoordInp, 0).rgb;';
|
||||
var rough = 'texpaint_pack_sample.g;';
|
||||
var met = 'texpaint_pack_sample.b;';
|
||||
var occ = 'texpaint_pack_sample.r;';
|
||||
var nortan = 'textureLod(texpaint_nor_undo, texCoordInp, 0).rgb;';
|
||||
var height = '0.0';
|
||||
var opac = '1.0';
|
||||
frag.write('vec3 basecol = $base;');
|
||||
frag.write('float roughness = $rough;');
|
||||
frag.write('float metallic = $met;');
|
||||
frag.write('float occlusion = $occ;');
|
||||
frag.write('vec3 nortan = $nortan;');
|
||||
frag.write('float height = $height;');
|
||||
frag.write('float opacity = $opac * brushOpacity;');
|
||||
}
|
||||
else {
|
||||
Cycles.parse_height_as_channel = true;
|
||||
var sout = Cycles.parse(UINodes.inst.canvas, con_paint, vert, frag, null, null, null, matcon);
|
||||
Cycles.parse_height_as_channel = false;
|
||||
var base = sout.out_basecol;
|
||||
var rough = sout.out_roughness;
|
||||
var met = sout.out_metallic;
|
||||
var occ = sout.out_occlusion;
|
||||
var nortan = Cycles.out_normaltan;
|
||||
var height = sout.out_height;
|
||||
var opac = sout.out_opacity;
|
||||
frag.write('vec3 basecol = $base;');
|
||||
frag.write('float roughness = $rough;');
|
||||
frag.write('float metallic = $met;');
|
||||
frag.write('float occlusion = $occ;');
|
||||
frag.write('vec3 nortan = $nortan;');
|
||||
frag.write('float height = $height;');
|
||||
frag.write('float opacity = $opac * brushOpacity;');
|
||||
}
|
||||
|
||||
if (UITrait.inst.brushType == 6) { // Text tool
|
||||
frag.add_uniform('sampler2D textexttool', '_textexttool');
|
||||
@@ -673,7 +705,8 @@ class MaterialBuilder {
|
||||
frag.write('vec2 posb = (prevwvpposition.xy / prevwvpposition.w) * 0.5 + 0.5;');
|
||||
|
||||
var writeTC = (UITrait.inst.brushType == 2 && UITrait.inst.fillTypeHandle.position == 1) || // Face fill
|
||||
UITrait.inst.brushType == 4; // Colorid pick
|
||||
UITrait.inst.brushType == 4 || // Colorid pick
|
||||
UITrait.inst.brushType == 8; // Clone
|
||||
|
||||
if (writeTC) {
|
||||
frag.write('fragColor[2] = vec4(posa - posb, texCoord.xy);');
|
||||
|
||||
+21
-2
@@ -54,14 +54,12 @@ class Uniforms {
|
||||
return vec2;
|
||||
}
|
||||
else if (link == '_texcoloridSize') {
|
||||
vec2.set(0, 0, 0);
|
||||
if (UITrait.inst.assets.length == 0) return vec2;
|
||||
var img = UITrait.inst.getImage(UITrait.inst.assets[UITrait.inst.colorIdHandle.position]);
|
||||
vec2.set(img.width, img.height, 0);
|
||||
return vec2;
|
||||
}
|
||||
else if (link == '_textrianglemapSize') {
|
||||
vec2.set(0, 0, 0);
|
||||
var res = Config.getTextureRes();
|
||||
vec2.set(res, res, 0);
|
||||
return vec2;
|
||||
@@ -76,6 +74,10 @@ class Uniforms {
|
||||
// trace(iron.App.w());
|
||||
// var f = armory.renderpath.Inc.getSuperSampling();
|
||||
}
|
||||
else if (link == '_cloneDelta') {
|
||||
vec2.set(UITrait.inst.cloneDeltaX, UITrait.inst.cloneDeltaY, 0);
|
||||
return vec2;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -113,6 +115,23 @@ class Uniforms {
|
||||
else if (link == "_texshapetool") { // Opacity map for shape
|
||||
return UITrait.inst.shapeToolImage;
|
||||
}
|
||||
else if (link == "_texpaint_undo") {
|
||||
// if (UITrait.inst.pushUndo && UITrait.inst.C.undo_steps > 0)
|
||||
var i = UITrait.inst.undoI - 1 < 0 ? UITrait.inst.C.undo_steps - 1 : UITrait.inst.undoI - 1;
|
||||
return iron.RenderPath.active.renderTargets.get("texpaint_undo" + i).image;
|
||||
}
|
||||
else if (link == "_texpaint_nor_undo") {
|
||||
var i = UITrait.inst.undoI - 1 < 0 ? UITrait.inst.C.undo_steps - 1 : UITrait.inst.undoI - 1;
|
||||
return iron.RenderPath.active.renderTargets.get("texpaint_nor_undo" + i).image;
|
||||
}
|
||||
else if (link == "_texpaint_pack_undo") {
|
||||
var i = UITrait.inst.undoI - 1 < 0 ? UITrait.inst.C.undo_steps - 1 : UITrait.inst.undoI - 1;
|
||||
return iron.RenderPath.active.renderTargets.get("texpaint_pack_undo" + i).image;
|
||||
}
|
||||
else if (link == "_texpaint_opt_undo") {
|
||||
var i = UITrait.inst.undoI - 1 < 0 ? UITrait.inst.C.undo_steps - 1 : UITrait.inst.undoI - 1;
|
||||
return iron.RenderPath.active.renderTargets.get("texpaint_opt_undo" + i).image;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,7 +246,9 @@ class RenderPathDeferred {
|
||||
}
|
||||
|
||||
// Read texcoords from gbuffer
|
||||
if (UITrait.inst.brushType == 2 && UITrait.inst.fillTypeHandle.position == 1) { // Face fill
|
||||
var readTC = (UITrait.inst.brushType == 2 && UITrait.inst.fillTypeHandle.position == 1) || // Face fill
|
||||
UITrait.inst.brushType == 8; // Clone
|
||||
if (readTC) {
|
||||
path.bindTarget("gbuffer2", "gbuffer2");
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ class FlyCamera extends iron.Trait {
|
||||
UITrait.inst.isScrolling ||
|
||||
UITrait.inst.cameraControls != 2 ||
|
||||
mouse.x < 0 ||
|
||||
mouse.x > iron.App.w()) return;
|
||||
mouse.x > iron.App.w() ||
|
||||
!mouse.down("right")) return;
|
||||
|
||||
var camera = iron.Scene.active.camera;
|
||||
|
||||
|
||||
+56
-17
@@ -118,6 +118,10 @@ class UITrait extends iron.Trait {
|
||||
public var lastPaintY = -1.0;
|
||||
public var painted = 0;
|
||||
public var brushTime = 0.0;
|
||||
public var cloneStartX = -1.0;
|
||||
public var cloneStartY = -1.0;
|
||||
public var cloneDeltaX = 0.0;
|
||||
public var cloneDeltaY = 0.0;
|
||||
|
||||
public var selectedObject:iron.object.Object;
|
||||
public var paintObject:iron.object.MeshObject;
|
||||
@@ -341,7 +345,20 @@ class UITrait extends iron.Trait {
|
||||
|
||||
var scale = C.window_scale;
|
||||
ui = new Zui( { theme: arm.App.theme, font: arm.App.font, scaleFactor: scale, color_wheel: arm.App.color_wheel } );
|
||||
loadBundled(['cursor.png', 'empty.jpg', 'tool_draw.png', 'tool_eraser.png', 'tool_fill.png', 'tool_bake.png', 'tool_colorid.png', 'tool_decal.png', 'tool_text.png','tool_shape.png', 'tool_particle.png'], done);
|
||||
loadBundled([
|
||||
'cursor.png',
|
||||
'empty.jpg',
|
||||
'tool_draw.png',
|
||||
'tool_eraser.png',
|
||||
'tool_fill.png',
|
||||
'tool_bake.png',
|
||||
'tool_colorid.png',
|
||||
'tool_decal.png',
|
||||
'tool_text.png',
|
||||
'tool_shape.png',
|
||||
'tool_clone.png',
|
||||
'tool_particle.png'
|
||||
], done);
|
||||
}
|
||||
|
||||
public function showMessage(s:String) {
|
||||
@@ -483,15 +500,17 @@ class UITrait extends iron.Trait {
|
||||
else if (kb.started("6")) selectMaterial(5);
|
||||
}
|
||||
|
||||
if (!ctrl) {
|
||||
if (!ctrl && !mouse.down("right")) {
|
||||
if (kb.started("b")) selectTool(0); // Brush
|
||||
else if (kb.started("r")) selectTool(1); // Erase
|
||||
else if (kb.started("e")) selectTool(1); // Erase
|
||||
else if (kb.started("g")) selectTool(2); // Fill
|
||||
else if (kb.started("k")) selectTool(3); // Bake
|
||||
else if (kb.started("c")) selectTool(4); // Color id
|
||||
else if (kb.started("l")) selectTool(5); // Decal
|
||||
else if (kb.started("d")) selectTool(5); // Decal
|
||||
else if (kb.started("t")) selectTool(6); // Text
|
||||
else if (kb.started("h")) selectTool(7); // Shape
|
||||
else if (kb.started("s")) selectTool(7); // Shape
|
||||
else if (kb.started("l")) selectTool(8); // Clone
|
||||
// else if (kb.started("p")) selectTool(8); // Particle
|
||||
}
|
||||
|
||||
// Radius
|
||||
@@ -631,14 +650,26 @@ class UITrait extends iron.Trait {
|
||||
if (down && !kb.down("control")) {
|
||||
if (mouse.x < iron.App.w() && mouse.x > iron.App.x() &&
|
||||
mouse.y < iron.App.h() && mouse.y > iron.App.y()) {
|
||||
if (brushTime == 0 && C.undo_steps > 0) { // Paint started
|
||||
pushUndo = true;
|
||||
if (projectPath != "") {
|
||||
kha.Window.get(0).title = arm.App.filenameHandle.text + "* - ArmorPaint";
|
||||
}
|
||||
|
||||
if (brushType == 8 && kb.down("alt")) { // Clone source
|
||||
cloneStartX = mouse.x;
|
||||
cloneStartY = mouse.y;
|
||||
}
|
||||
else {
|
||||
if (brushTime == 0 && C.undo_steps > 0) { // Paint started
|
||||
pushUndo = true;
|
||||
if (projectPath != "") {
|
||||
kha.Window.get(0).title = arm.App.filenameHandle.text + "* - ArmorPaint";
|
||||
}
|
||||
if (brushType == 8 && cloneStartX >= 0.0) { // Clone delta
|
||||
cloneDeltaX = (cloneStartX - mouse.x) / iron.App.w();
|
||||
cloneDeltaY = (cloneStartY - mouse.y) / iron.App.h();
|
||||
cloneStartX = -1;
|
||||
}
|
||||
}
|
||||
brushTime += iron.system.Time.delta;
|
||||
for (f in _onBrush) f(0);
|
||||
}
|
||||
brushTime += iron.system.Time.delta;
|
||||
for (f in _onBrush) f(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1011,7 +1042,8 @@ class UITrait extends iron.Trait {
|
||||
var img6 = bundled.get("tool_decal.png");
|
||||
var img7 = bundled.get("tool_text.png");
|
||||
var img8 = bundled.get("tool_shape.png");
|
||||
var img9 = bundled.get("tool_particle.png");
|
||||
var img9 = bundled.get("tool_clone.png");
|
||||
// var img10 = bundled.get("tool_particle.png");
|
||||
|
||||
ui._x += 2;
|
||||
if (brushType == 0) ui.rect(-1, -1, img1.width + 2, img1.height + 2, ui.t.HIGHLIGHT_COL, 2);
|
||||
@@ -1023,7 +1055,7 @@ class UITrait extends iron.Trait {
|
||||
ui._x += 2;
|
||||
if (brushType == 1) ui.rect(-1, -1, img1.width + 2, img1.height + 2, ui.t.HIGHLIGHT_COL, 2);
|
||||
if (ui.image(img2) == State.Started) selectTool(1);
|
||||
if (ui.isHovered) ui.tooltip("Eraser (R)");
|
||||
if (ui.isHovered) ui.tooltip("Eraser (E)");
|
||||
ui._x -= 2;
|
||||
ui._y += 2;
|
||||
|
||||
@@ -1044,14 +1076,14 @@ class UITrait extends iron.Trait {
|
||||
ui._x += 2;
|
||||
if (brushType == 4) ui.rect(-1, -1, img1.width + 2, img1.height + 2, ui.t.HIGHLIGHT_COL, 2);
|
||||
if (ui.image(img5) == State.Started) selectTool(4);
|
||||
if (ui.isHovered) ui.tooltip("Color ID (F)");
|
||||
if (ui.isHovered) ui.tooltip("Color ID (C)");
|
||||
ui._x -= 2;
|
||||
ui._y += 2;
|
||||
|
||||
ui._x += 2;
|
||||
if (brushType == 5) ui.rect(-1, -1, img1.width + 2, img1.height + 2, ui.t.HIGHLIGHT_COL, 2);
|
||||
if (ui.image(img6) == State.Started) selectTool(5);
|
||||
if (ui.isHovered) ui.tooltip("Decal (L)");
|
||||
if (ui.isHovered) ui.tooltip("Decal (D)");
|
||||
ui._x -= 2;
|
||||
ui._y += 2;
|
||||
|
||||
@@ -1065,7 +1097,14 @@ class UITrait extends iron.Trait {
|
||||
ui._x += 2;
|
||||
if (brushType == 7) ui.rect(-1, -1, img1.width + 2, img1.height + 2, ui.t.HIGHLIGHT_COL, 2);
|
||||
if (ui.image(img8) == State.Started) selectTool(7);
|
||||
if (ui.isHovered) ui.tooltip("Shape (H)");
|
||||
if (ui.isHovered) ui.tooltip("Shape (S)");
|
||||
ui._x -= 2;
|
||||
ui._y += 2;
|
||||
|
||||
ui._x += 2;
|
||||
if (brushType == 8) ui.rect(-1, -1, img1.width + 2, img1.height + 2, ui.t.HIGHLIGHT_COL, 2);
|
||||
if (ui.image(img9) == State.Started) selectTool(8);
|
||||
if (ui.isHovered) ui.tooltip("Clone (L) - Hold ALT to set source");
|
||||
ui._x -= 2;
|
||||
ui._y += 2;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user