Parcourir la source

Adding MaterialSelector.hx prefab to apply shader on a specific pass given its name.

clementlandrin il y a 10 mois
Parent
commit
e9ecd6e390
2 fichiers modifiés avec 99 ajouts et 1 suppressions
  1. 85 0
      hrt/prefab/MaterialSelector.hx
  2. 14 1
      hrt/prefab/Shader.hx

+ 85 - 0
hrt/prefab/MaterialSelector.hx

@@ -0,0 +1,85 @@
+package hrt.prefab;
+
+typedef MaterialSelection = {
+	passName : String,
+}
+
+class MaterialSelector extends hrt.prefab.Prefab {
+
+	@:s public var selections : Array<MaterialSelection> = []; 
+
+	public function getPasses(local3d: h3d.scene.Object = null) : Array<h3d.mat.Pass> {
+		if (local3d == null)
+			local3d = findFirstLocal3d();
+		var mats = local3d.getMaterials();
+		var passes = [];
+		for ( m in mats ) {
+			for ( selection in selections ) {
+				if ( selection.passName == "all" || selection.passName == "mainPass" ) {
+					passes.push(m.mainPass);
+					break;
+				} else {
+					var p = m.getPass(selection.passName);
+					if ( p != null )
+						passes.push(p);
+				}
+			}
+		}
+		return passes;
+	}
+
+	#if editor
+	override function getHideProps() : hide.prefab.HideProps {
+		return {
+			icon : "cog",
+			name : "Material Selector",
+		};
+	}
+
+	override function edit( ctx : hide.prefab.EditContext ) {
+		super.edit(ctx);
+
+		var e1 = new hide.Element('
+			<div class="group" name="Selections">
+				<ul id="selections"></ul>
+			</div>
+		');
+		ctx.properties.add(e1, function(propName) {
+			ctx.onChange(this, propName);
+			ctx.rebuildPrefab(this);
+		});
+
+		var list = e1.find("ul#selections");
+		for ( s in selections ) {
+			var es = new hide.Element('
+			<div class="group" name="Selection">
+				<dl>
+					<dt>Pass Name</dt><dd><input type="text" field="passName"/></dd>
+				</dl>
+			</div>
+			');
+			es.appendTo(list);
+			ctx.properties.build(es, s, (pname) -> {
+				updateInstance("selections");
+				ctx.rebuildPrefab(this, true);
+			});
+		}
+		var add = new hide.Element('<li><p><a href="#">[+]</a></p></li>');
+		add.appendTo(list);
+		add.find("a").click(function(_) {
+			selections.push({ 
+				passName : "",
+			});
+			ctx.rebuildProperties();
+		});
+		var sub = new hide.Element('<li><p><a href="#">[-]</a></p></li>');
+		sub.appendTo(list);
+		sub.find("a").click(function(_) {
+			selections.pop();
+			ctx.rebuildProperties();
+		});
+	}
+	#end
+
+	static var _ = Prefab.register("materialSelector", MaterialSelector);
+}

+ 14 - 1
hrt/prefab/Shader.hx

@@ -8,6 +8,8 @@ import hide.prefab.HideProps;
 #end
 class Shader extends Prefab {
 
+	static final PASS_SELECT = "$PASS_SELECT";
+
 	@:s var targetMaterial : String;
 	@:s var recursiveApply = true;
 
@@ -83,7 +85,10 @@ class Shader extends Prefab {
 	}
 
 	function applyShader( obj : h3d.scene.Object, material : h3d.mat.Material, shader : hxsl.Shader ) {
-		material.mainPass.addShader(shader);
+		if ( material.name == PASS_SELECT )
+			@:privateAccess material.mainPass.addSelfShader(shader);
+		else
+			material.mainPass.addShader(shader);
 	}
 
 	function removeShader( obj : h3d.scene.Object, material : h3d.mat.Material, shader : hxsl.Shader ) {
@@ -103,6 +108,14 @@ class Shader extends Prefab {
 			var material : Material = cast parent;
 			for( m in material.getMaterials(true) )
 					callb(null, m);
+		} else if ( Std.isOfType(parent, MaterialSelector) ) {
+			var materialSelector = cast(parent, MaterialSelector);
+			var passSelect = h3d.mat.MaterialSetup.current.createMaterial();
+			passSelect.name = PASS_SELECT;
+			for ( p in materialSelector.getPasses() ) {
+				@:privateAccess passSelect.passes = p;
+				callb(null, passSelect);
+			}
 		} else {
 			var objs = [];
 			function pushUnique(obj : h3d.scene.Object ) {