Bläddra i källkod

added console, added materials view/hide/switch texture

ncannasse 8 år sedan
förälder
incheckning
b7d50caa72
2 ändrade filer med 208 tillägg och 69 borttagningar
  1. 90 16
      tools/fbx/TreeView.hx
  2. 118 53
      tools/fbx/Viewer.hx

+ 90 - 16
tools/fbx/TreeView.hx

@@ -68,6 +68,8 @@ class TreeView
 	public var y(default, set) : Float;
 	public var selected : TreeView;
 
+	public static var currentOver : TreeView;
+
 	public function new (o, parent = null) {
 		if(cont == null)
 			throw("TreeView must be initialized");
@@ -89,17 +91,27 @@ class TreeView
 			isdummy = true;
 
 		if(parent == null) {
+
+			function getCur(e:hxd.Event) {
+				var id = Std.int(e.relY / height);
+				return curr[id];
+			}
+
 			bt.onOver = function(e:hxd.Event) {
 				fg.visible = true;
+				currentOver = getCur(e);
 			}
 			bt.onOut = function(e:hxd.Event) {
 				fg.visible = false;
 				if(!select.visible)
 					setHighligth(null);
+				currentOver = null;
 			}
 			bt.onMove = function(e:hxd.Event) {
 				var id = Std.int(e.relY / height);
 				fg.y = id * height;
+				currentOver = getCur(e);
+
 				if(!select.visible){
 					select.y = id * height;
 					setHighligth(curr[id]);
@@ -107,8 +119,7 @@ class TreeView
 				else setHighligth(curr[Std.int(select.y / height)]);
 			}
 			bt.onClick = function(e:hxd.Event) {
-				var id = Std.int(e.relY / height);
-				var row = curr[id];
+				var row = getCur(e);
 
 				selected = row;
 
@@ -141,13 +152,19 @@ class TreeView
 							}
 						}
 				}
-				e.propagate = false;
+
+				bt.onMove(e);
 			}
 			bt.onWheel = function(e : hxd.Event) {
 				cont.y -= e.wheelDelta * height * 3;
-				e.propagate = false;
 			};
-			bt.onPush = function(e : hxd.Event) { e.propagate = false; }
+
+			bt.onKeyDown = function(e) {
+				e.propagate = true;
+			};
+			bt.onKeyUp = function(e) {
+				e.propagate = true;
+			};
 
 			getObjectsLib(this);
 			draw();
@@ -155,16 +172,13 @@ class TreeView
 	}
 
 	public function onKey(e:hxd.Event) {
-		if( selected == null ) return;
-		if( e.keyCode == "V".code ) {
-			selected.obj.visible = !selected.obj.visible;
-			draw();
-		}
+		if( e.keyCode == "V".code )
+			obj.visible = !obj.visible;
 	}
 
 	function setHighligth(e : TreeView) {
 		if(highlight != null) {
-			for( m in highlight.obj.getMaterials() )
+			for( m in highlight.getMaterials() )
 				m.mainPass.removeShader(m.mainPass.getShader(h3d.shader.ColorAdd));
 			var skin = highlight.joints != null ? highlight : null;
 			if(skin == null && highlight.parent != null)
@@ -208,6 +222,15 @@ class TreeView
 				e.childs.push(child);
 				getObjectsRec(child);
 			}
+			if( Viewer.props.materials ) {
+				var m = e.obj.isMesh() ? e.obj.toMesh() : null;
+				var mm = Std.instance(m, h3d.scene.MultiMaterial);
+				var mats = if( mm != null ) mm.materials else if( m != null && m.material.name != null ) [m.material] else [];
+				for( m in mats ) {
+					var child = new TreeMaterial(e.obj, e, m);
+					e.childs.push(child);
+				}
+			}
 		}
 		getObjectsRec(parent);
 	}
@@ -245,7 +268,6 @@ class TreeView
 			select = new h2d.Bitmap(h2d.Tile.fromColor(0), cont);
 			select.visible = false;
 			bt = new h2d.Interactive(0, 0, cont);
-			bt.propagateEvents = true;
 
 			var t = Res.dot.toTile();
 			t.dx -= t.width >> 1;
@@ -275,6 +297,15 @@ class TreeView
 				}
 	}
 
+	function getName() {
+		var str = obj.toString();
+		return StringTools.startsWith(str, "Mesh(Joint(") ? str.substr(5, str.length - 6) : str;
+	}
+
+	function isVisible() {
+		return obj.visible;
+	}
+
 	public function draw(level = 0) {
 		if(level == 0)
 			clear();
@@ -293,10 +324,9 @@ class TreeView
 
 		if(tf != null) tf.remove();
 		tf = new h2d.Text(font, cont);
-		var str = obj.toString();
-		tf.text = str.indexOf("Joint") != -1 ? str.substr(5, str.length - 6) : str;
+		tf.text = getName();
 
-		tf.color.setColor(obj.visible ? 0xFFFFFFFF : 0xFF808080);
+		tf.color.setColor(isVisible() ? 0xFFFFFFFF : 0xFF808080);
 		tf.x = 5 + dx;
 		tf.y = 1 + minHeight;
 
@@ -324,6 +354,9 @@ class TreeView
 		return showJoints = b;
 	}
 
+	function getMaterials() {
+		return obj.getMaterials();
+	}
 
 	function setDummy(?o : h3d.scene.Object) {
 		if(o == null) {
@@ -352,7 +385,7 @@ class TreeView
 			if(highlight != null) {
 				var s = 0.8 + 0.2 * Math.sin(cpt);
 				var color = new h3d.Vector(vect.x * s, vect.y * s, vect.z * s);
-				for( m in highlight.obj.getMaterials() ) {
+				for( m in highlight.getMaterials() ) {
 					m.mainPass.removeShader(m.mainPass.getShader(h3d.shader.ColorAdd));
 					m.mainPass.addShader(new h3d.shader.ColorAdd(color.toColor()));
 				}
@@ -398,4 +431,45 @@ class TreeView
 		for(c in childs)
 			c.trace(level + 1);
 	}
+}
+
+class TreeMaterial extends TreeView {
+
+	var mat : h3d.mat.MeshMaterial;
+
+	public function new(o, parent, mat) {
+		this.mat = mat;
+		super(o, parent);
+	}
+
+	override function getObjectsLib(parent:TreeView) {
+		// nothing
+	}
+
+	override function getName() {
+		return "Material" + mat.name;
+	}
+
+	override function onKey(e:hxd.Event) {
+		switch( e.keyCode ) {
+		case "V".code:
+			mat.mainPass.culling = (mat.mainPass.culling == Both ? None : Both);
+		case "T".code:
+			hxd.File.browse(function(sel) {
+				sel.load(function(bytes) {
+					mat.texture = hxd.res.Any.fromBytes("", bytes).toTexture();
+				});
+			},{ fileTypes : [{ name : "Texture", extensions : ["png","gif","jpg","jpeg"] }] });
+		default:
+		}
+	}
+
+	override function getMaterials() : Array<h3d.mat.Material> {
+		return [mat];
+	}
+
+	override function isVisible() {
+		return mat.mainPass.culling != Both && super.isVisible();
+	}
+
 }

+ 118 - 53
tools/fbx/Viewer.hx

@@ -17,6 +17,7 @@ typedef Props = {
 	queueAnims:Bool,
 	treeview:Bool,
 	checker:Bool,
+	materials:Bool,
 }
 
 class Viewer extends hxd.App {
@@ -41,6 +42,7 @@ class Viewer extends hxd.App {
 	var box : h3d.scene.Object;
 	var alib : hxd.fmt.fbx.Library;
 	var ahmd : hxd.fmt.hmd.Library;
+	var freezeCamera : Bool;
 
 	var tree : TreeView;
 	var checker : h3d.scene.Mesh;
@@ -63,10 +65,11 @@ class Viewer extends hxd.App {
 			showAxis:true, showBones:false, showBox:false,
 			speed:1., loop:true,
 			lights : true, normals : false,
-			convertHMD : false,
+			convertHMD : true,
 			queueAnims:false,
 			treeview:true,
 			checker:false,
+			materials:false,
 		};
 		props = hxd.Save.load(props);
 		props.speed = 1;
@@ -96,7 +99,6 @@ class Viewer extends hxd.App {
 
 		tf_help = new h2d.Text(font, s2d);
 		tf_help.x = 5;
-		tf_help.y = s2d.height - 25;
 		tf_help.text = "[H] Show/Hide keys";
 
 		var len = 10;
@@ -121,12 +123,17 @@ class Viewer extends hxd.App {
 			s3d.addChild(axis);
 		else
 			s3d.removeChild(axis);
+
+
+		initConsole();
+		onResize();
 	}
 
 	override function onResize() {
 		tf.x = s2d.width - (tf.maxWidth + 5);
-		tf_help.y = s2d.height - 25;
+		tf_help.y = s2d.height - 35;
 		tf_keys.y = s2d.height - tf_keys.textHeight - 35;
+		tf_keys.x = tf_help.x = s2d.width - 250;
 	}
 
 	function onEvent( e : hxd.Event ) {
@@ -183,31 +190,6 @@ class Viewer extends hxd.App {
 			props.treeview = !props.treeview;
 			if(tree != null)
 				tree.visible = props.treeview;
-		case "G".code:
-			props.checker = !props.checker;
-			showChecker(props.checker);
-
-		case "R".code:
-			if( props.convertHMD ) return;
-			rightHand = !rightHand;
-			cam.pos.x *= -1;
-			cam.target.x *= -1;
-			reload = true;
-		case "K".code:
-			props.showBones = !props.showBones;
-			setMaterial();
-		case "Y".code:
-			props.showAxis = !props.showAxis;
-			if( props.showAxis )
-				s3d.addChild(axis);
-			else
-				s3d.removeChild(axis);
-		case "M".code:
-			props.smoothing = !props.smoothing;
-			setMaterial();
-		case "N".code:
-			props.normals = !props.normals;
-			setMaterial();
 		case "B".code:
 			props.showBox = !props.showBox;
 			if( props.showBox && box != null )
@@ -247,7 +229,11 @@ class Viewer extends hxd.App {
 		case "Q".code:
 			props.queueAnims = !props.queueAnims;
 		default:
-			tree.onKey(e);
+			var over = TreeView.currentOver;
+			if( over != null ) {
+				over.onKey(e);
+				tree.draw();
+			}
 		}
 
 		if( reload && curData != null )
@@ -265,7 +251,8 @@ class Viewer extends hxd.App {
 		});
 		l.addEventListener(flash.events.Event.COMPLETE, function(_) {
 			loadData(haxe.io.Bytes.ofData(l.data));
-			resetCamera();
+			if( !freezeCamera )
+				resetCamera();
 			if( newFbx )
 				save();
 		});
@@ -352,7 +339,8 @@ class Viewer extends hxd.App {
 					ahmd = null;
 					props.curFile = sel.fileName;
 					loadData(bytes);
-					resetCamera();
+					if( !freezeCamera )
+						resetCamera();
 					save();
 				}
 			});
@@ -424,11 +412,7 @@ class Viewer extends hxd.App {
 
 		box = new h3d.scene.Box(0xFFFF9910);
 
-		TreeView.init(s2d);
-		tree = new TreeView(obj);
-		tree.x = 0;
-		tree.y = 0;
-		tree.visible = props.treeview;
+		initTree();
 
 		setMaterial();
 		setAnim();
@@ -437,11 +421,30 @@ class Viewer extends hxd.App {
 		save();
 	}
 
+	function initTree() {
+		TreeView.init(s2d);
+		tree = new TreeView(obj);
+		tree.x = 0;
+		tree.y = 0;
+		tree.visible = props.treeview;
+	}
+
 	function getInfos(obj : h3d.scene.Object) {
 		var tri = 0, objs = 0, verts = 0;
 		function getObjectsRec( o : h3d.scene.Object) {
+
+			// auto hide meshes with special names
+			if( o.name != null && (o.name.toLowerCase().indexOf("selection") != -1 || o.name.toLowerCase().indexOf("collide") != -1) ) {
+				var mats = o.getMaterials();
+				if( o.numChildren == 0 && mats.length == 1 && Std.instance(mats[0], h3d.mat.MeshMaterial).texture == null )
+					o.visible = false;
+			}
+
+			if( !o.visible ) return;
+
 			objs++;
-			if(o.isMesh()) {
+
+			if( o.isMesh() ) {
 				tri += o.toMesh().primitive.triCount();
 				verts += o.toMesh().primitive.vertexCount();
 			}
@@ -538,8 +541,12 @@ class Viewer extends hxd.App {
 			if( multi != null ) materials = multi.materials;
 			for( m in materials ) {
 				if( m == null ) continue;
-				if( m.texture != null )
+				if( m.texture != null ) {
 					m.texture.filter = props.smoothing ? Linear : Nearest;
+					m.textureShader.killAlpha = true;
+					m.textureShader.killAlphaThreshold = 0.5;
+				}
+				m.mainPass.culling = None;
 			}
 			var s = Std.instance(o, h3d.scene.Skin);
 			if( s != null )
@@ -548,11 +555,14 @@ class Viewer extends hxd.App {
 				tree.showJoints = props.showBones;
 			if( props.normals ) {
 				if( m.name != "__normals__" ) {
-					var n = new h3d.scene.Mesh(m.primitive.buildNormalsDisplay(), m);
-					n.material.color.set(0, 0, 1);
-					n.material.mainPass.culling = None;
-					n.material.mainPass.addShader(new h3d.shader.LineShader()).lengthScale = 0.2;
-					n.name = "__normals__";
+					var buf = try m.primitive.buildNormalsDisplay() catch( e : Dynamic ) null;
+					if( buf != null ) {
+						var n = new h3d.scene.Mesh(buf, m);
+						n.material.color.set(0, 0, 1);
+						n.material.mainPass.culling = None;
+						n.material.mainPass.addShader(new h3d.shader.LineShader()).lengthScale = 0.2;
+						n.name = "__normals__";
+					}
 				}
 			} else if( m.name == "__normals__" )
 				m.remove();
@@ -614,6 +624,67 @@ class Viewer extends hxd.App {
 		}
 	}
 
+	function initConsole() {
+
+		function reload() {
+			if( curData != null ) loadData(curData);
+		}
+
+		var console = new h2d.Console(hxd.res.DefaultFont.get(), s2d);
+		console.addCommand("materials", [], function() {
+			props.materials = !props.materials;
+			save();
+			initTree();
+		});
+		console.addCommand("axis", [], function() {
+			props.showAxis = !props.showAxis;
+			if( props.showAxis )
+				s3d.addChild(axis);
+			else
+				s3d.removeChild(axis);
+			save();
+		});
+		console.addCommand("righthand", [], function() {
+			if( props.convertHMD ) {
+				console.log("Only in FBX");
+				return;
+			}
+			rightHand = !rightHand;
+			s3d.camera.pos.x *= -1;
+			s3d.camera.target.x *= -1;
+			reload();
+		});
+
+		console.addCommand("normals", [], function() {
+			props.normals = !props.normals;
+			save();
+			setMaterial();
+		});
+
+		console.addCommand("freezeCamera", [], function() {
+			freezeCamera = !freezeCamera;
+			ctrl.visible = !freezeCamera;
+		});
+
+		console.addCommand("ground", [], function() {
+			props.checker = !props.checker;
+			save();
+			showChecker(props.checker);
+		});
+
+		console.addCommand("joints", [], function() {
+			props.showBones = !props.showBones;
+			save();
+			setMaterial();
+		});
+
+		console.addCommand("smooth", [], function() {
+			props.smoothing = !props.smoothing;
+			save();
+			setMaterial();
+		});
+	}
+
 	override function update( dt : Float ) {
 
 		if(tree != null)
@@ -642,25 +713,19 @@ class Viewer extends hxd.App {
 			"[F2] Load animation",
 			"[A] Animation = " + loadAnim,
 			"[L] Loop = "+props.loop,
-			"[Y] Axis = "+props.showAxis,
-			"[K] Bones = "+props.showBones,
 			"[B] Bounds = "+props.showBox+(box == null ? "" : " ["+fmt(box.scaleX)+" x "+fmt(box.scaleY)+" x "+fmt(box.scaleZ)+"]"),
 			"[S] Slow Animation",
-			"[+/-] Speed Animation = "+props.speed,
-			"[R] Right-Hand Camera = "+rightHand,
-			"[M] Tex Smoothing = " + props.smoothing,
-			"[N] Show normals = "+props.normals,
+			"[+/-] Speed Animation = "+Std.int(props.speed*100)+"%",
 			"[I] Lights = " + props.lights,
 			"[C] Use HMD model = " + props.convertHMD,
 			"[Q] Queue anims = "+props.queueAnims,
 			"[O] Show/Hide treeview = "+props.treeview,
 			"[V] Show/Hide selected object",
-			"[G] Show/Hide ground = "+props.checker,
-			"",
+			"[T] Change material texture",
 			"[F] Default camera",
 			"[Space/P] Pause Animation",
 			"[LMB + Move] Rotation",
-			"[RMB + Move] translation",
+			"[RMB + Move] Translation",
 			"[Wheel] Zoom"
 		].join("\n");
 		tf_keys.y = s2d.height - tf_keys.textHeight - 35;
@@ -680,7 +745,7 @@ class Viewer extends hxd.App {
 		hxd.Timer.tmod *= props.speed;
 	}
 
-	static var inst : Viewer;
+	public static var inst : Viewer;
 
 	static function initAIR() {
 		#if air3