Directional brush

This commit is contained in:
luboslenco
2020-03-16 22:07:24 +01:00
parent 16fc75fa98
commit 2afe3f703e
11 changed files with 95 additions and 39 deletions
+1 -1
View File
@@ -1 +1 @@
{"name":"Brush","nodes":[{"id":3,"name":"Input","type":"InputNode","x":83,"y":192,"color":-11959648,"inputs":[{"id":3,"node_id":3,"name":"Lazy Radius","type":"VALUE","color":-6184543,"default_value":0.0},{"id":3,"node_id":3,"name":"Lazy Step","type":"VALUE","color":-6184543,"default_value":0.0}],"outputs":[{"id":3,"node_id":3,"name":"Position","type":"VECTOR","color":-10238109,"default_value":null}],"buttons":[]},{"id":5,"name":"Brush Output","type":"BrushOutputNode","x":311,"y":192,"color":-11959648,"inputs":[{"id":5,"node_id":5,"name":"Position","type":"VECTOR","color":-10238109,"default_value":[0,0,0]},{"id":5,"node_id":5,"name":"Radius","type":"VALUE","color":-6184543,"default_value":1.0},{"id":5,"node_id":5,"name":"Opacity","type":"VALUE","color":-6184543,"default_value":1},{"id":5,"node_id":5,"name":"Hardness","type":"VALUE","color":-6184543,"default_value":1},{"id":5,"node_id":5,"name":"UV Scale","type":"VALUE","color":-6184543,"default_value":1.0},{"id":5,"node_id":5,"name":"Stencil","type":"VALUE","color":-6184543,"default_value":1.0}],"outputs":[],"buttons":[]}],"links":[{"id":0,"from_id":3,"from_socket":0,"to_id":5,"to_socket":0}]}
{"name":"Brush","nodes":[{"id":3,"name":"Input","type":"InputNode","x":83,"y":218,"color":-11959648,"inputs":[{"id":3,"node_id":3,"name":"Lazy Radius","type":"VALUE","color":-6184543,"default_value":0.0},{"id":3,"node_id":3,"name":"Lazy Step","type":"VALUE","color":-6184543,"default_value":0.0}],"outputs":[{"id":3,"node_id":3,"name":"Position","type":"VECTOR","color":-10238109,"default_value":null}],"buttons":[]},{"id":5,"name":"Brush Output","type":"BrushOutputNode","x":311,"y":192,"color":-11959648,"inputs":[{"id":5,"node_id":5,"name":"Position","type":"VECTOR","color":-10238109,"default_value":[0,0,0]},{"id":5,"node_id":5,"name":"Radius","type":"VALUE","color":-6184543,"default_value":1.0},{"id":5,"node_id":5,"name":"Scale","type":"VALUE","color":-6184543,"default_value":1.0},{"id":5,"node_id":5,"name":"Angle","type":"VALUE","color":-6184543,"default_value":0.0},{"id":5,"node_id":5,"name":"Opacity","type":"VALUE","color":-6184543,"default_value":1.0},{"id":5,"node_id":5,"name":"Hardness","type":"VALUE","color":-6184543,"default_value":1.0},{"id":5,"node_id":5,"name":"Stencil","type":"VALUE","color":-6184543,"default_value":1.0}],"outputs":[],"buttons":[{"name": "Directional","type": "BOOL","default_value": false,"output": 0}]}],"links":[{"id":0,"from_id":3,"from_socket":0,"to_id":5,"to_socket":0}]}
+2 -2
View File
@@ -30,8 +30,8 @@ class LayerSlot {
public var blending = BlendMix;
public var objectMask = 0;
public var uvScale = 1.0;
public var uvRot = 0.0;
public var scale = 1.0;
public var angle = 0.0;
public var uvType = UVMap;
public var paintBase = true;
public var paintOpac = true;
+2 -2
View File
@@ -53,8 +53,8 @@ class ExportArm {
texpaint_nor: l.texpaint_nor != null ? Lz4.encode(l.texpaint_nor.getPixels()) : null,
texpaint_pack: l.texpaint_pack != null ? Lz4.encode(l.texpaint_pack.getPixels()) : null,
texpaint_mask: l.texpaint_mask != null ? Lz4.encode(l.texpaint_mask.getPixels()) : null,
uv_scale: l.uvScale,
uv_rot: l.uvRot,
uv_scale: l.scale,
uv_rot: l.angle,
uv_type: l.uvType,
opacity_mask: l.maskOpacity,
material_mask: l.material_mask != null ? Project.materials.indexOf(l.material_mask) : -1,
+2 -2
View File
@@ -232,8 +232,8 @@ class ImportArm {
l.texpaint_mask.g2.end();
}
l.uvScale = ld.uv_scale;
l.uvRot = ld.uv_rot;
l.scale = ld.uv_scale;
l.angle = ld.uv_rot;
l.uvType = ld.uv_type;
l.maskOpacity = ld.opacity_mask;
l.material_mask = ld.material_mask > -1 ? Project.materials[ld.material_mask] : null;
+15 -1
View File
@@ -243,13 +243,27 @@ class MakePaint {
frag.write('binp_mask.x *= aspectRatio;');
frag.write('binp_mask = binp_mask * 0.5 + 0.5;');
frag.write('vec2 pa_mask = bsp.xy - binp_mask.xy;');
// if (UITrait.inst.brushDirectional) {
// frag.add_uniform('vec2 brushDirection', '_brushDirection');
// frag.write('pa_mask.xy = vec2(pa_mask.x * brushDirection.x - pa_mask.y * brushDirection.y, pa_mask.x * brushDirection.y + pa_mask.y * brushDirection.x);');
// }
if (UITrait.inst.brushDirectional) {
frag.write('float maskAngle = atan2(-inp.y + inplast.y, inp.x - inplast.x) - 3.141592 / 2;');
frag.write('pa_mask.xy = vec2(pa_mask.x * cos(maskAngle) - pa_mask.y * sin(maskAngle), pa_mask.x * sin(maskAngle) + pa_mask.y * cos(maskAngle));');
}
var angle = UITrait.inst.brushAngle + UITrait.inst.brushNodesAngle;
if (angle != 0.0) {
var a = angle * (Math.PI / 180);
frag.write('pa_mask.xy = vec2(pa_mask.x * ${Math.cos(a)} - pa_mask.y * ${Math.sin(a)}, pa_mask.x * ${Math.sin(a)} + pa_mask.y * ${Math.cos(a)});');
}
frag.write('pa_mask /= brushRadius;');
if (UITrait.inst.brush3d) {
frag.add_uniform('vec3 eye', '_cameraPosition');
frag.write('pa_mask *= distance(eye, winp.xyz) / 1.5;');
}
frag.write('pa_mask = pa_mask.xy * 0.5 + 0.5;');
frag.write('opacity *= textureLod(texbrushmask, pa_mask, 0.0).r;');
frag.write('float4 mask_sample = textureLod(texbrushmask, pa_mask, 0.0);');
frag.write('opacity *= mask_sample.r * mask_sample.a;');
}
if (Context.tool == ToolParticle) { // particle mask
+16 -6
View File
@@ -31,9 +31,18 @@ class MakeTexcoord {
frag.write_attrib('vec2 texCoord = uvsp * brushScale;');
var uvRot = Context.layer.material_mask != null ? Context.layer.uvRot : UITrait.inst.brushRot;
if (uvRot > 0.0) {
var a = uvRot * (Math.PI / 180);
// if (UITrait.inst.brushDirectional) {
// frag.add_uniform('vec2 brushDirection', '_brushDirection');
// frag.write('texCoord = vec2(texCoord.x * brushDirection.x - texCoord.y * brushDirection.y, texCoord.x * brushDirection.y + texCoord.y * brushDirection.x);');
// }
if (UITrait.inst.brushDirectional) {
frag.write('float maskAngleBrush = atan2(-inp.y + inplast.y, inp.x - inplast.x) - 3.141592 / 2;');
frag.write('texCoord = vec2(texCoord.x * cos(maskAngleBrush) - texCoord.y * sin(maskAngleBrush), texCoord.x * sin(maskAngleBrush) + texCoord.y * cos(maskAngleBrush));');
}
var angle = UITrait.inst.brushAngle + UITrait.inst.brushNodesAngle;
var uvAngle = Context.layer.material_mask != null ? Context.layer.angle : angle;
if (uvAngle != 0.0) {
var a = uvAngle * (Math.PI / 180);
frag.write('texCoord = vec2(texCoord.x * ${Math.cos(a)} - texCoord.y * ${Math.sin(a)}, texCoord.x * ${Math.sin(a)} + texCoord.y * ${Math.cos(a)});');
}
}
@@ -42,9 +51,10 @@ class MakeTexcoord {
vert.add_out('vec2 texCoord');
vert.write('texCoord = subtex * brushScale;');
var uvRot = Context.layer.material_mask != null ? Context.layer.uvRot : UITrait.inst.brushRot;
if (uvRot > 0.0) {
var a = uvRot * (Math.PI / 180);
var angle = UITrait.inst.brushAngle + UITrait.inst.brushNodesAngle;
var uvAngle = Context.layer.material_mask != null ? Context.layer.angle : angle;
if (uvAngle > 0.0) {
var a = uvAngle * (Math.PI / 180);
vert.write('texCoord = vec2(texCoord.x * ${Math.cos(a)} - texCoord.y * ${Math.sin(a)}, texCoord.x * ${Math.sin(a)} + texCoord.y * ${Math.cos(a)});');
}
}
+24 -9
View File
@@ -72,6 +72,22 @@ class NodesBrush {
// {
// id: 0,
// node_id: 0,
// name: "Scale",
// type: "VALUE",
// color: 0xffa1a1a1,
// default_value: 1.0
// },
// {
// id: 0,
// node_id: 0,
// name: "Angle",
// type: "VALUE",
// color: 0xffa1a1a1,
// default_value: 0.0
// },
// {
// id: 0,
// node_id: 0,
// name: "Opacity",
// type: "VALUE",
// color: 0xffa1a1a1,
@@ -88,14 +104,6 @@ class NodesBrush {
// {
// id: 0,
// node_id: 0,
// name: "UV Scale",
// type: "VALUE",
// color: 0xffa1a1a1,
// default_value: 1.0
// },
// {
// id: 0,
// node_id: 0,
// name: "Stencil",
// type: "VALUE",
// color: 0xffa1a1a1,
@@ -103,7 +111,14 @@ class NodesBrush {
// }
// ],
// outputs: [],
// buttons: []
// buttons: [
// {
// name: "Directional",
// type: "BOOL",
// default_value: false,
// output: 0
// }
// ]
// },
{
id: 0,
+9 -4
View File
@@ -7,6 +7,8 @@ import arm.Tool;
@:keep
class BrushOutputNode extends LogicNode {
public var Directional = false; // button 0
public function new(tree: LogicTree) {
super(tree);
UITrait.inst.runBrush = run;
@@ -19,8 +21,10 @@ class BrushOutputNode extends LogicNode {
UITrait.inst.paintVec = inputs[0].get();
UITrait.inst.brushNodesRadius = inputs[1].get();
UITrait.inst.brushNodesScale = inputs[2].get();
UITrait.inst.brushNodesAngle = inputs[3].get();
var opac: Dynamic = inputs[2].get(); // Float or texture name
var opac: Dynamic = inputs[4].get(); // Float or texture name
if (opac == null) opac = 1.0;
if (Std.is(opac, String)) {
UITrait.inst.brushNodesOpacity = 1.0;
@@ -33,10 +37,9 @@ class BrushOutputNode extends LogicNode {
UITrait.inst.brushMaskImage = null;
}
UITrait.inst.brushNodesHardness = inputs[3].get();
UITrait.inst.brushNodesScale = inputs[4].get();
UITrait.inst.brushNodesHardness = inputs[5].get();
var stencil: Dynamic = inputs[5].get(); // Float or texture name
var stencil: Dynamic = inputs[6].get(); // Float or texture name
if (stencil == null) stencil = 1.0;
if (Std.is(stencil, String)) {
var index = Project.assetNames.indexOf(stencil);
@@ -51,6 +54,8 @@ class BrushOutputNode extends LogicNode {
lastStencil != UITrait.inst.brushStencilImage) {
MaterialParser.parsePaintMaterial();
}
UITrait.inst.brushDirectional = Directional;
}
override function run(from: Int) {
+11 -1
View File
@@ -56,7 +56,7 @@ class Uniforms {
if (link == "_brushScale") {
var nodesScale = UITrait.inst.brushNodesScale;
var fill = Context.layer.material_mask != null;
var val = (fill ? Context.layer.uvScale : UITrait.inst.brushScale) * nodesScale;
var val = (fill ? Context.layer.scale : UITrait.inst.brushScale) * nodesScale;
return val;
}
if (link == "_texpaintSize") {
@@ -134,6 +134,16 @@ class Uniforms {
vec2.set(UITrait.inst.cloneDeltaX, UITrait.inst.cloneDeltaY, 0);
return vec2;
}
if (link == "_brushDirection") {
var x = UITrait.inst.paintVec.x;
var y = UITrait.inst.paintVec.y;
var lastx = UITrait.inst.lastPaintVecX;
var lasty = UITrait.inst.lastPaintVecY;
if (UITrait.inst.paint2d) { x -= 1.0; lastx -= 1.0; }
var angle = Math.atan2(-y + lasty, x - lastx) - Math.PI / 2;
vec2.set(Math.cos(angle), Math.sin(angle), 0);
return vec2;
}
#end
return null;
}
+6 -6
View File
@@ -554,17 +554,17 @@ class TabLayers {
ui.row([8 / 100, 92 / 100 / 3, 92 / 100 / 3, 92 / 100 / 3]);
@:privateAccess ui.endElement();
var uvScaleHandle = Id.handle().nest(l.id, {value: l.uvScale});
l.uvScale = ui.slider(uvScaleHandle, "UV Scale", 0.0, 5.0, true);
if (uvScaleHandle.changed) {
var scaleHandle = Id.handle().nest(l.id, {value: l.scale});
l.scale = ui.slider(scaleHandle, "Scale", 0.0, 5.0, true);
if (scaleHandle.changed) {
Context.setMaterial(l.material_mask);
Context.setLayer(l);
Layers.updateFillLayers();
}
var uvRotHandle = Id.handle().nest(l.id, {value: l.uvRot});
l.uvRot = ui.slider(uvRotHandle, "UV Rotate", 0.0, 360, true, 1);
if (uvRotHandle.changed) {
var angleHandle = Id.handle().nest(l.id, {value: l.angle});
l.angle = ui.slider(angleHandle, "Angle", 0.0, 360, true, 1);
if (angleHandle.changed) {
Context.setMaterial(l.material_mask);
Context.setLayer(l);
MaterialParser.parsePaintMaterial();
+7 -5
View File
@@ -181,7 +181,9 @@ class UITrait {
public var brushStencilScale = 0.9;
public var brushStencilScaling = false;
public var brushNodesScale = 1.0;
public var brushNodesAngle = 0.0;
public var brushNodesHardness = 1.0;
public var brushDirectional = false;
public var brushRadius = 0.5;
public var brushRadiusHandle = new Handle({value: 0.5});
@@ -191,7 +193,7 @@ class UITrait {
public var brushOpacity = 1.0;
public var brushOpacityHandle = new Handle({value: 1.0});
public var brushScale = 1.0;
public var brushRot = 0.0;
public var brushAngle = 0.0;
public var brushHardness = 0.8;
public var brushLazyRadius = 0.0;
public var brushLazyStep = 0.0;
@@ -1162,7 +1164,7 @@ class UITrait {
Context.tool == ToolDecal ||
Context.tool == ToolText) {
var brushScaleHandle = Id.handle({value: brushScale});
brushScale = ui.slider(brushScaleHandle, "UV Scale", 0.01, 5.0, true);
brushScale = ui.slider(brushScaleHandle, "Scale", 0.01, 5.0, true);
if (brushScaleHandle.changed) {
if (Context.tool == ToolDecal || Context.tool == ToolText) {
ui.g.end();
@@ -1171,9 +1173,9 @@ class UITrait {
}
}
var brushRotHandle = Id.handle({value: brushRot});
brushRot = ui.slider(brushRotHandle, "UV Rotate", 0.0, 360.0, true, 1);
if (brushRotHandle.changed) {
var brushAngleHandle = Id.handle({value: brushAngle});
brushAngle = ui.slider(brushAngleHandle, "Angle", 0.0, 360.0, true, 1);
if (brushAngleHandle.changed) {
MaterialParser.parsePaintMaterial();
}
}