Directional brush
This commit is contained in:
@@ -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}]}
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)});');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user