luboslenco пре 6 година
родитељ
комит
a16722cd72

+ 3 - 1
Sources/arm/nodes/Logic.hx

@@ -98,7 +98,9 @@ class Logic {
 		for (i in 0...5) {
 			for (b in node.buttons) {
 				if (b.name == 'property' + i) {
-					Reflect.setProperty(v, b.name, b.data[b.default_value]);
+					var arrayData = Std.is(b.data, Array);
+					var texts = arrayData ? b.data : Nodes.getEnumTexts();
+					Reflect.setProperty(v, b.name, texts[b.default_value]);
 				}
 			}
 		}

+ 16 - 1
Sources/arm/nodes/MaterialBuilder.hx

@@ -208,7 +208,7 @@ class MaterialBuilder {
 					// Non-continuous
 					// frag.write('float dist = distance(wposition, winp.xyz);');
 				}
-				else { // !paint3d
+				else { // !brush3d
 					frag.write('vec2 binp = inp.xy * 2.0 - 1.0;');
 					frag.write('binp.x *= aspectRatio;');
 					frag.write('binp = binp * 0.5 + 0.5;');
@@ -468,6 +468,21 @@ class MaterialBuilder {
 			frag.write('opacity *= textureLod(textexttool, texCoord, 0.0).r;');
 		}
 
+		if (UITrait.inst.brushMaskImage != null && Context.tool == ToolBrush) {
+			frag.add_uniform('sampler2D texbrushmask', '_texbrushmask');
+			frag.write('vec2 binp_mask = inp.xy * 2.0 - 1.0;');
+			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;');
+			frag.write('pa_mask /= brushRadius;');
+			if (UITrait.inst.brush3d) {
+				frag.add_uniform('vec3 eye', '_cameraPosition');
+				frag.write('pa_mask *= distance(eye, winp) / 1.5;');
+			}
+			frag.write('pa_mask = pa_mask.xy * 0.5 + 0.5;');
+			frag.write('opacity *= textureLod(texbrushmask, pa_mask, 0).r;');
+		}
+
 		if (Context.tool == ToolParticle) { // particle mask
 			frag.add_uniform('sampler2D texparticle', '_texparticle');
 			#if (kha_opengl || kha_webgl)

+ 54 - 53
Sources/arm/nodes/NodesBrush.hx

@@ -28,58 +28,58 @@ class NodesBrush {
 				],
 				buttons: []
 			},
-			{
-				id: 0,
-				name: "Brush Output",
-				type: "BrushOutputNode",
-				x: 0,
-				y: 0,
-				color: 0xff4982a0,
-				inputs: [
-					{
-						id: 0,
-						node_id: 0,
-						name: "Position",
-						type: "VECTOR",
-						color: 0xff63c763,
-						default_value: [0.0, 0.0, 0.0]
-					},
-					{
-						id: 0,
-						node_id: 0,
-						name: "Radius",
-						type: "VALUE",
-						color: 0xffa1a1a1,
-						default_value: 1.0
-					},
-					{
-						id: 0,
-						node_id: 0,
-						name: "Opacity",
-						type: "VALUE",
-						color: 0xffa1a1a1,
-						default_value: 1.0
-					},
-					{
-						id: 0,
-						node_id: 0,
-						name: "Hardness",
-						type: "VALUE",
-						color: 0xffa1a1a1,
-						default_value: 1.0
-					},
-					{
-						id: 0,
-						node_id: 0,
-						name: "UV Scale",
-						type: "VALUE",
-						color: 0xffa1a1a1,
-						default_value: 1.0
-					}
-				],
-				outputs: [],
-				buttons: []
-			},
+			// {
+			// 	id: 0,
+			// 	name: "Brush Output",
+			// 	type: "BrushOutputNode",
+			// 	x: 0,
+			// 	y: 0,
+			// 	color: 0xff4982a0,
+			// 	inputs: [
+			// 		{
+			// 			id: 0,
+			// 			node_id: 0,
+			// 			name: "Position",
+			// 			type: "VECTOR",
+			// 			color: 0xff63c763,
+			// 			default_value: [0.0, 0.0, 0.0]
+			// 		},
+			// 		{
+			// 			id: 0,
+			// 			node_id: 0,
+			// 			name: "Radius",
+			// 			type: "VALUE",
+			// 			color: 0xffa1a1a1,
+			// 			default_value: 1.0
+			// 		},
+			// 		{
+			// 			id: 0,
+			// 			node_id: 0,
+			// 			name: "Opacity",
+			// 			type: "VALUE",
+			// 			color: 0xffa1a1a1,
+			// 			default_value: 1.0
+			// 		},
+			// 		{
+			// 			id: 0,
+			// 			node_id: 0,
+			// 			name: "Hardness",
+			// 			type: "VALUE",
+			// 			color: 0xffa1a1a1,
+			// 			default_value: 1.0
+			// 		},
+			// 		{
+			// 			id: 0,
+			// 			node_id: 0,
+			// 			name: "UV Scale",
+			// 			type: "VALUE",
+			// 			color: 0xffa1a1a1,
+			// 			default_value: 1.0
+			// 		}
+			// 	],
+			// 	outputs: [],
+			// 	buttons: []
+			// },
 			{
 				id: 0,
 				name: "Value",
@@ -378,7 +378,8 @@ class NodesBrush {
 				],
 				buttons: [
 					{
-						name: "File",
+						// name: "File",
+						name: "property0",
 						type: "ENUM",
 						default_value: 0,
 						data: ""

+ 17 - 4
Sources/arm/nodes/brush/BrushOutputNode.hx

@@ -9,13 +9,28 @@ class BrushOutputNode extends LogicNode {
 
 	public function new(tree:LogicTree) {
 		super(tree);
-		UITrait.inst.notifyOnBrush(run);
+		UITrait.inst.onBrush = run;
 	}
 
 	override function run(from:Int) {
 		UITrait.inst.paintVec = inputs[0].get();
 		UITrait.inst.brushNodesRadius = inputs[1].get();
-		UITrait.inst.brushNodesOpacity = inputs[2].get();
+		var opac:Dynamic = inputs[2].get(); // Float or texture name
+		if (opac == null) opac = 1.0;
+		var lastMask = UITrait.inst.brushMaskImage;
+		if (Std.is(opac, String)) {
+			UITrait.inst.brushNodesOpacity = 1.0;
+			var index = Project.assetNames.indexOf(opac);
+			var asset = Project.assets[index];
+			UITrait.inst.brushMaskImage = UITrait.inst.getImage(asset);
+		}
+		else {
+			UITrait.inst.brushNodesOpacity = opac;
+			UITrait.inst.brushMaskImage = null;
+		}
+		if (lastMask != UITrait.inst.brushMaskImage) {
+			MaterialParser.parsePaintMaterial();
+		}
 		UITrait.inst.brushNodesHardness = inputs[3].get();
 		UITrait.inst.brushNodesScale = inputs[4].get();
 
@@ -67,7 +82,5 @@ class BrushOutputNode extends LogicNode {
 				Context.rdirty = 2;
 			}
 		}
-
-		runOutput(0);
 	}
 }

+ 15 - 0
Sources/arm/nodes/brush/TEX_IMAGE.hx

@@ -0,0 +1,15 @@
+package arm.nodes.brush;
+
+@:keep
+class TEX_IMAGE extends LogicNode {
+
+	public var property0:String; // file
+
+	public function new(tree:LogicTree) {
+		super(tree);
+	}
+
+	override function get(from:Int):Dynamic {
+		return property0;
+	}
+}

+ 3 - 0
Sources/arm/render/Uniforms.hx

@@ -121,6 +121,9 @@ class Uniforms {
 		else if (link == "_texdecalmask") { // Opacity map for decal
 			return UITrait.inst.decalMaskImage;
 		}
+		else if (link == "_texbrushmask") {
+			return UITrait.inst.brushMaskImage;
+		}
 		else if (link == "_texpaint_undo") {
 			var i = History.undoI - 1 < 0 ? Config.raw.undo_steps - 1 : History.undoI - 1;
 			return RenderPath.active.renderTargets.get("texpaint_undo" + i).image;

+ 2 - 1
Sources/arm/ui/UINodes.hx

@@ -68,6 +68,7 @@ class UINodes {
 		inst = this;
 
 		Nodes.excludeRemove.push("OUTPUT_MATERIAL_PBR");
+		Nodes.excludeRemove.push("BrushOutputNode");
 		// Cycles.arm_export_tangents = false;
 
 		Data.getBlob('defaults/default_material.json', function(b1:Blob) {
@@ -418,7 +419,7 @@ class UINodes {
 			var canvas = canvasType == 0 ? canvas : canvasBrush;
 			var numNodes = list[menuCategory].length;
 			
-			var ph = numNodes * 20 * ui.SCALE;
+			var ph = numNodes * 22 * ui.SCALE;
 			var py = popupY;
 			g.color = ui.t.WINDOW_BG_COL;
 			var menuw = Std.int(ew * 1.6);

+ 3 - 7
Sources/arm/ui/UITrait.hx

@@ -124,8 +124,7 @@ class UITrait {
 
 	public var layerFilter = 0;
 
-	var onBrush:Array<Int->Void> = [];
-
+	public var onBrush:Int->Void = null;
 	public var paintVec = new Vec4();
 	public var lastPaintX = -1.0;
 	public var lastPaintY = -1.0;
@@ -148,6 +147,7 @@ class UITrait {
 
 	public var brushNodesRadius = 1.0;
 	public var brushNodesOpacity = 1.0;
+	public var brushMaskImage:Image = null;
 	public var brushNodesScale = 1.0;
 	public var brushNodesHardness = 1.0;
 
@@ -229,10 +229,6 @@ class UITrait {
 	public var worktab = Id.handle({position: 0});
 	public var toolNames = ["Brush", "Eraser", "Fill", "Decal", "Text", "Clone", "Blur", "Particle", "Bake", "ColorID", "Picker"];
 
-	public function notifyOnBrush(f:Int->Void) {
-		onBrush.push(f);
-	}
-
 	public function new() {
 		inst = this;
 
@@ -621,7 +617,7 @@ class UITrait {
 						}
 					}
 					brushTime += Time.delta;
-					for (f in onBrush) f(0);
+					if (onBrush != null) onBrush(0);
 				}
 			}