Nicolas Cannasse 11 лет назад
Родитель
Сommit
39cd59bf5a
6 измененных файлов с 113 добавлено и 29 удалено
  1. 4 0
      h3d/prim/HMDModel.hx
  2. 1 1
      hxd/fmt/fbx/BaseLibrary.hx
  3. 12 9
      hxd/fmt/fbx/HMDOut.hx
  4. 1 0
      hxd/fmt/fbx/Library.hx
  5. 4 0
      hxd/res/Any.hx
  6. 91 19
      tools/fbx/Viewer.hx

+ 4 - 0
h3d/prim/HMDModel.hx

@@ -12,6 +12,10 @@ class HMDModel extends MeshPrimitive {
 		this.entry = entry;
 		this.entry = entry;
 	}
 	}
 
 
+	override function getBounds() {
+		return new h3d.col.Bounds();
+	}
+
 	override function alloc(engine:h3d.Engine) {
 	override function alloc(engine:h3d.Engine) {
 		dispose();
 		dispose();
 		buffer = new h3d.Buffer(data.vertexCount, data.vertexStride);
 		buffer = new h3d.Buffer(data.vertexCount, data.vertexStride);

+ 1 - 1
hxd/fmt/fbx/BaseLibrary.hx

@@ -923,7 +923,7 @@ class BaseLibrary {
 		return keepJoints.get(j.name);
 		return keepJoints.get(j.name);
 	}
 	}
 
 
-	function createSkin( hskins : Map<Int,h3d.anim.Skin>, hgeom : Map<Int,#if (dataOnly || macro) {function getVerticesCount():Int;function setSkin(s:h3d.anim.Skin):Void;} #else h3d.prim.FBXModel #end>, rootJoints : Array<h3d.anim.Skin.Joint>, bonesPerVertex ) {
+	function createSkin( hskins : Map<Int,h3d.anim.Skin>, hgeom : Map<Int,{function getVerticesCount():Int;function setSkin(s:h3d.anim.Skin):Void;}>, rootJoints : Array<h3d.anim.Skin.Joint>, bonesPerVertex ) {
 		var allJoints = [];
 		var allJoints = [];
 		function collectJoints(j:h3d.anim.Skin.Joint) {
 		function collectJoints(j:h3d.anim.Skin.Joint) {
 			// collect subs first (allow easy removal of terminal unskinned joints)
 			// collect subs first (allow easy removal of terminal unskinned joints)

+ 12 - 9
hxd/fmt/fbx/HMDOut.hx

@@ -9,6 +9,7 @@ class HMDOut extends BaseLibrary {
 	var dataOut : haxe.io.BytesOutput;
 	var dataOut : haxe.io.BytesOutput;
 	var filePath : String;
 	var filePath : String;
 	var tmp = haxe.io.Bytes.alloc(4);
 	var tmp = haxe.io.Bytes.alloc(4);
+	public var absoluteTexturePath : Bool;
 
 
 	function int32tof( v : Int ) : Float {
 	function int32tof( v : Int ) : Float {
 		tmp.set(0, v & 0xFF);
 		tmp.set(0, v & 0xFF);
@@ -114,7 +115,7 @@ class HMDOut extends BaseLibrary {
 				}
 				}
 
 
 				// look if the vertex already exists
 				// look if the vertex already exists
-				var found = null;
+				var found : Null<Int> = null;
 				for( vid in 0...g.vertexCount ) {
 				for( vid in 0...g.vertexCount ) {
 					var same = true;
 					var same = true;
 					var p = vid * stride;
 					var p = vid * stride;
@@ -318,14 +319,16 @@ class HMDOut extends BaseLibrary {
 					var path = texture.get("FileName").props[0].toString();
 					var path = texture.get("FileName").props[0].toString();
 					if( path != "" ) {
 					if( path != "" ) {
 						path = path.split("\\").join("/");
 						path = path.split("\\").join("/");
-						if( filePath != null && StringTools.startsWith(path.toLowerCase(), filePath) )
-							path = path.substr(filePath.length);
-						else {
-							// relative resource path
-							var k = path.split("/res/");
-							if( k.length > 1 ) {
-								k.shift();
-								path = k.join("/res/");
+						if( !absoluteTexturePath ) {
+							if( filePath != null && StringTools.startsWith(path.toLowerCase(), filePath) )
+								path = path.substr(filePath.length);
+							else {
+								// relative resource path
+								var k = path.split("/res/");
+								if( k.length > 1 ) {
+									k.shift();
+									path = k.join("/res/");
+								}
 							}
 							}
 						}
 						}
 						mat.diffuseTexture = path;
 						mat.diffuseTexture = path;

+ 1 - 0
hxd/fmt/fbx/Library.hx

@@ -105,6 +105,7 @@ class Library extends BaseLibrary {
 			}
 			}
 		}
 		}
 		// build skins
 		// build skins
+		var hgeom = [for( k in hgeom.keys() ) k => (hgeom.get(k) : {function getVerticesCount():Int;function setSkin(s:h3d.anim.Skin):Void;})];
 		for( o in objects ) {
 		for( o in objects ) {
 			if( o.isJoint ) continue;
 			if( o.isJoint ) continue;
 
 

+ 4 - 0
hxd/res/Any.hx

@@ -31,6 +31,10 @@ class Any extends Resource {
 		return loader.loadFbxModel(entry.path).toFbx(loader);
 		return loader.loadFbxModel(entry.path).toFbx(loader);
 	}
 	}
 
 
+	public function toHmd() {
+		return loader.loadFbxModel(entry.path).toHmd();
+	}
+
 	public function toAwd() {
 	public function toAwd() {
 		return loader.loadAwdModel(entry.path);
 		return loader.loadAwdModel(entry.path);
 	}
 	}

+ 91 - 19
tools/fbx/Viewer.hx

@@ -13,6 +13,7 @@ typedef Props = {
 	loop:Bool,
 	loop:Bool,
 	lights:Bool,
 	lights:Bool,
 	normals:Bool,
 	normals:Bool,
+	convertHMD:Bool,
 }
 }
 
 
 typedef Campos = {
 typedef Campos = {
@@ -33,7 +34,9 @@ class Viewer extends hxd.App {
 	var tf_help : flash.text.TextField;
 	var tf_help : flash.text.TextField;
 
 
 	var curFbx : hxd.fmt.fbx.Library;
 	var curFbx : hxd.fmt.fbx.Library;
+	var curHmd : hxd.fmt.hmd.Library;
 	static public var curData : String;
 	static public var curData : String;
+	static public var curDataSize : Int;
 	static public var props : Props;
 	static public var props : Props;
 	static public var animMode : h3d.anim.Mode = LinearAnim;
 	static public var animMode : h3d.anim.Mode = LinearAnim;
 
 
@@ -45,6 +48,7 @@ class Viewer extends hxd.App {
 	var axis : h3d.scene.Graphics;
 	var axis : h3d.scene.Graphics;
 	var box : h3d.scene.Object;
 	var box : h3d.scene.Object;
 	var alib : hxd.fmt.fbx.Library;
 	var alib : hxd.fmt.fbx.Library;
+	var ahmd : hxd.fmt.hmd.Library;
 
 
 	function new() {
 	function new() {
 		super();
 		super();
@@ -57,7 +61,15 @@ class Viewer extends hxd.App {
 		freeMove = false;
 		freeMove = false;
 		rightClick = false;
 		rightClick = false;
 
 
-		props = { curFile : "", camPos : { x:10, y:0, z:0, tx:0, ty:0, tz:0 }, smoothing:true, showAxis:true, showBones:false, showBox:false, slowDown:false, loop:true, lights : true, normals : false }
+		props = {
+			curFile : "",
+			camPos : { x:10, y:0, z:0, tx:0, ty:0, tz:0 },
+			smoothing:true,
+			showAxis:true, showBones:false, showBox:false,
+			slowDown:false, loop:true,
+			lights : true, normals : false,
+			convertHMD : false,
+		};
 		props = hxd.Save.load(props);
 		props = hxd.Save.load(props);
 
 
 		tf = new flash.text.TextField();
 		tf = new flash.text.TextField();
@@ -250,6 +262,9 @@ class Viewer extends hxd.App {
 		case "I".code:
 		case "I".code:
 			props.lights = !props.lights;
 			props.lights = !props.lights;
 			setMaterial();
 			setMaterial();
+		case "C".code:
+			props.convertHMD = !props.convertHMD;
+			reload = true;
 		default:
 		default:
 
 
 		}
 		}
@@ -267,7 +282,7 @@ class Viewer extends hxd.App {
 			if( newFbx ) haxe.Log.trace("Failed to load " + file,null);
 			if( newFbx ) haxe.Log.trace("Failed to load " + file,null);
 		});
 		});
 		l.addEventListener(flash.events.Event.COMPLETE, function(_) {
 		l.addEventListener(flash.events.Event.COMPLETE, function(_) {
-			loadData(l.data, newFbx);
+			loadData(l.data);
 			if( newFbx ) {
 			if( newFbx ) {
 				resetCamera();
 				resetCamera();
 				save();
 				save();
@@ -336,13 +351,19 @@ class Viewer extends hxd.App {
 				haxe.Log.clear();
 				haxe.Log.clear();
 				var content = bytes.toString();
 				var content = bytes.toString();
 				if( anim ) {
 				if( anim ) {
-					alib = new hxd.fmt.fbx.Library();
-					var fbx = hxd.fmt.fbx.Parser.parse(content);
-					alib.load(fbx);
-					if( !rightHand )
-						alib.leftHandConvert();
+					if( props.convertHMD ) {
+						ahmd = fbxToHmd(content).toHmd();
+					} else {
+						alib = new hxd.fmt.fbx.Library();
+						var fbx = hxd.fmt.fbx.Parser.parse(content);
+						alib.load(fbx);
+						if( !rightHand )
+							alib.leftHandConvert();
+					}
 					setAnim();
 					setAnim();
 				} else {
 				} else {
+					alib = null;
+					ahmd = null;
 					props.curFile = sel.fileName;
 					props.curFile = sel.fileName;
 					loadData(content);
 					loadData(content);
 					resetCamera();
 					resetCamera();
@@ -352,18 +373,59 @@ class Viewer extends hxd.App {
 		},{ fileTypes : [{ name : "FBX File", extensions : ["fbx"] }], defaultPath : props.curFile });
 		},{ fileTypes : [{ name : "FBX File", extensions : ["fbx"] }], defaultPath : props.curFile });
 	}
 	}
 
 
-	function loadData( data : String, newFbx = true ) {
-		curFbx = new hxd.fmt.fbx.Library();
-		curFbx.unskinnedJointsAsObjects = true;
+	function fbxToHmd( data : String ) {
+		var hmdOut = new hxd.fmt.fbx.HMDOut();
+		hmdOut.absoluteTexturePath = true;
+		hmdOut.loadTextFile(data);
+		var hmd = hmdOut.toHMD(null, true);
+		var out = new haxe.io.BytesOutput();
+		new hxd.fmt.hmd.Writer(out).write(hmd);
+		var bytes = out.getBytes();
+		return hxd.res.Any.fromBytes("model.hmd", bytes);
+	}
+
+	function loadData( data : String ) {
+
 		curData = data;
 		curData = data;
-		var fbx = hxd.fmt.fbx.Parser.parse(data);
-		curFbx.load(fbx);
-		if( !rightHand )
-			curFbx.leftHandConvert();
+		curDataSize = data.length;
 
 
-		var frame = obj.currentAnimation == null ? 0 : obj.currentAnimation.frame;
 		obj.remove();
 		obj.remove();
-		obj = curFbx.makeObject(textureLoader);
+
+		curFbx = null;
+		curHmd = null;
+
+		if( props.convertHMD ) {
+
+			var res = fbxToHmd(data);
+			curDataSize = res.entry.getBytes().length;
+			curHmd = res.toHmd();
+
+			obj = curHmd.makeObject(function(name) {
+				var t = new h3d.mat.Texture(1, 1);
+				t.clear(0xFF00FF);
+				loadTexture(name, new h3d.mat.MeshMaterial(t));
+				return t;
+			});
+
+			for( m in obj.getMaterials() ) {
+				m.mainPass.culling = None;
+				m.mainPass.getShader(h3d.shader.Texture).killAlpha = true;
+				if( m.mainPass.blendDst == Zero ) m.mainPass.blend(SrcAlpha, OneMinusSrcAlpha);
+			}
+
+		} else {
+
+			curFbx = new hxd.fmt.fbx.Library();
+			curFbx.unskinnedJointsAsObjects = true;
+			var fbx = hxd.fmt.fbx.Parser.parse(data);
+			curFbx.load(fbx);
+			if( !rightHand )
+				curFbx.leftHandConvert();
+
+			obj = curFbx.makeObject(textureLoader);
+
+		}
+
 		s3d.addChild(obj);
 		s3d.addChild(obj);
 
 
 		//
 		//
@@ -432,7 +494,11 @@ class Viewer extends hxd.App {
 	}
 	}
 
 
 	function setAnim() {
 	function setAnim() {
-		var anim = curFbx.loadAnimation(animMode, null, null, alib);
+		var anim;
+		if( curHmd != null )
+			anim = (ahmd == null ? curHmd : ahmd).loadAnimation();
+		else
+			anim = curFbx.loadAnimation(animMode, null, null, alib);
 		if( anim != null ) {
 		if( anim != null ) {
 			anim = s3d.playAnimation(anim);
 			anim = s3d.playAnimation(anim);
 			if( !props.loop ) {
 			if( !props.loop ) {
@@ -532,7 +598,8 @@ class Viewer extends hxd.App {
 			"[M] Tex Smoothing = " + props.smoothing,
 			"[M] Tex Smoothing = " + props.smoothing,
 			"[N] Show normals = "+props.normals,
 			"[N] Show normals = "+props.normals,
 			"[F] Default camera",
 			"[F] Default camera",
-			"[I] Lights = "+props.lights,
+			"[I] Lights = " + props.lights,
+			"[C] Use HMD model = "+props.convertHMD,
 			"[1~4] Views",
 			"[1~4] Views",
 			"",
 			"",
 			"[Space] Pause Animation",
 			"[Space] Pause Animation",
@@ -542,9 +609,14 @@ class Viewer extends hxd.App {
 		].join("\n");
 		].join("\n");
 		tf_keys.y = s2d.height - tf_keys.textHeight - 35;
 		tf_keys.y = s2d.height - tf_keys.textHeight - 35;
 
 
+		var file = props.curFile.split("/").pop().split("\\").pop();
+		if( props.convertHMD && StringTools.endsWith(file.toLowerCase(), ".fbx") )
+			file = file.substr(0, -3) + "hmd";
+
+		file += " (" + Math.ceil(curDataSize / 1024) + "KB)";
 		tf.text = [
 		tf.text = [
 			(cam.rightHanded ? "R " : "") + fmt(hxd.Timer.fps()),
 			(cam.rightHanded ? "R " : "") + fmt(hxd.Timer.fps()),
-			props.curFile.split("/").pop().split("\\").pop(),
+			file,
 			(engine.drawTriangles - (props.showBox ? 26 : 0) - (props.showAxis ? 0 : 0)) + " tri",
 			(engine.drawTriangles - (props.showBox ? 26 : 0) - (props.showAxis ? 0 : 0)) + " tri",
 		].join("\n");
 		].join("\n");