Przeglądaj źródła

various fixes for hmd

Nicolas Cannasse 11 lat temu
rodzic
commit
dd21785ab5

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

@@ -615,7 +615,11 @@ class BaseLibrary {
 		}
 
 		var allTimes = [for( a in allTimes ) a];
-		
+
+		// no animation curve was found
+		if( allTimes.length == 0 )
+			return null;
+
 		allTimes.sort(sortDistinctFloats);
 		var maxTime = allTimes[allTimes.length - 1];
 		var minDT = maxTime;

+ 13 - 2
hxd/fmt/fbx/Data.hx

@@ -90,11 +90,22 @@ class FbxTools {
 		return false;
 	}
 
+	static inline function idToInt( f : Float ) {
+		#if neko
+		f %= 4294967296.;
+		if( f >= 2147483648. )
+			f -= 4294967296.;
+		else if( f < -2147483648. )
+			f += 4294967296.;
+		#end
+		return Std.int(f);
+	}
+
 	public static function toInt( n : FbxProp ) {
 		if( n == null ) throw "null prop";
 		return switch( n ) {
 		case PInt(v): v;
-		case PFloat(f): return Std.int( f );
+		case PFloat(f): idToInt(f);
 		default: throw "Invalid prop " + n;
 		}
 	}
@@ -121,7 +132,7 @@ class FbxTools {
 			throw n.name + " is not an object";
 		return switch( n.props[0] ) {
 		case PInt(id): id;
-		case PFloat(id) : Std.int( id );
+		case PFloat(id) : idToInt(id);
 		default: throw n.name + " is not an object " + n.props;
 		}
 	}

+ 18 - 7
hxd/fmt/fbx/Geometry.hx

@@ -104,14 +104,25 @@ class Geometry {
 		// merge colors
 		var colors = getColors();
 		var colors2 = g.getColors();
-		if( (colors != null) != (colors2 != null) )
-			throw "Different Color layer in merged objects";
 		if( colors != null ) {
-			var count = colors.values.length >> 2;
-			for( v in colors2.values )
-				colors.values.push(v);
-			for( i in colors2.index )
-				colors.index.push(i + count);
+			if( colors2 != null ) {
+				var count = colors.values.length >> 2;
+				for( v in colors2.values )
+					colors.values.push(v);
+				for( i in colors2.index )
+					colors.index.push(i + count);
+			} else {
+				var count = colors.values.length >> 2;
+				var count2 = Std.int(g.getNormals().length / 3); // quick guess for vertex count
+				colors.values.push(1);
+				colors.values.push(1);
+				colors.values.push(1);
+				colors.values.push(1);
+				for( i in 0...count2 )
+					colors.index.push(count);
+			}
+		} else if( colors2 != null ) {
+			// ignore colors, would require to create a FBX Node
 		}
 
 		// merge materials

+ 52 - 11
hxd/fmt/fbx/HMDOut.hx

@@ -32,6 +32,18 @@ class HMDOut extends BaseLibrary {
 		var colors = geom.getColors();
 		var mats = geom.getMaterials();
 
+		// remove empty color data
+		if( colors != null ) {
+			var hasData = false;
+			for( v in colors.values )
+				if( v < 0.99 ) {
+					hasData = true;
+					break;
+				}
+			if( !hasData )
+				colors = null;
+		}
+
 		// build format
 		g.vertexFormat = [
 			new GeometryFormat("position", DVec3),
@@ -154,8 +166,14 @@ class HMDOut extends BaseLibrary {
 				}
 			}
 			// by-material index
-			else if( mats != null ) {
-				var mid = mats[matPos++];
+			else {
+				var mid;
+				if( mats == null )
+					mid = 0;
+				else {
+					mid = mats[matPos];
+					if( mats.length > 1 ) matPos++;
+				}
 				var idx = ibufs[mid];
 				if( idx == null ) {
 					idx = new hxd.IndexBuffer();
@@ -178,13 +196,23 @@ class HMDOut extends BaseLibrary {
 			dataOut.writeFloat(vbuf[i]);
 		g.indexPosition = dataOut.length;
 		g.indexCounts = [];
+
+		var matMap = [], matCount = 0;
 		for( idx in ibufs ) {
+			if( idx == null ) {
+				matCount++;
+				continue;
+			}
+			matMap.push(matCount++);
 			g.indexCounts.push(idx.length);
 			for( i in idx )
 				dataOut.writeUInt16(i);
 		}
 
-		return g;
+		if( skin != null && skin.isSplit() )
+			matMap = null;
+
+		return { g : g, materials : matMap };
 	}
 
 	function addGeometry() {
@@ -286,7 +314,7 @@ class HMDOut extends BaseLibrary {
 		for( g in this.root.getAll("Objects.Geometry") )
 			tmpGeom.set(g.getId(), { setSkin : function(_) { }, getVerticesCount : function() return Std.int(new hxd.fmt.fbx.Geometry(this, g).getVertices().length/3) } );
 
-		var hgeom = new Map<Int,Int>();
+		var hgeom = new Map();
 		var hmat = new Map<Int,Int>();
 		var index = 0;
 		for( o in objects ) {
@@ -403,15 +431,28 @@ class HMDOut extends BaseLibrary {
 				model.skin = makeSkin(skin, o.skin);
 			}
 
-			var gid = hgeom.get(g.getId());
-			if( gid == null ) {
+			var gdata = hgeom.get(g.getId());
+			if( gdata == null ) {
 				var geom = buildGeom(new hxd.fmt.fbx.Geometry(this, g), skin, dataOut);
-				gid = d.geometries.length;
-				d.geometries.push(geom);
-				hgeom.set(g.getId(), gid);
+				gdata = { gid : d.geometries.length, materials : geom.materials };
+				d.geometries.push(geom.g);
+				hgeom.set(g.getId(), gdata);
+			}
+			model.geometry = gdata.gid;
+
+			if( mids.length == 0 ) {
+				var mat = new Material();
+				mat.blendMode = None;
+				mat.culling = Back;
+				mat.name = "default";
+				var mid = d.materials.length;
+				d.materials.push(mat);
+				mids = [mid];
 			}
-			model.geometry = gid;
-			model.materials = mids;
+			if( gdata.materials == null )
+				model.materials = mids;
+			else
+				model.materials = [for( id in gdata.materials ) mids[id]];
 		}
 	}
 

+ 39 - 1
hxd/fmt/hmd/MakeAll.hx

@@ -2,8 +2,46 @@ package hxd.fmt.hmd;
 
 class MakeAll {
 
+	static var INVALID_CHARS = ~/[^A-Za-z0-9_]/g;
+
+	static function loop( dir : String ) {
+		for( f in sys.FileSystem.readDirectory(dir) ) {
+			var path = dir + "/" + f;
+			if( sys.FileSystem.isDirectory(path) ) {
+				loop(path);
+				continue;
+			}
+			if( !StringTools.endsWith(f.toLowerCase(), ".fbx") )
+				continue;
+			var relPath = path.substr(4);
+			var target = "res/.tmp/R_" + INVALID_CHARS.replace(relPath, "_") + ".hmd";
+			var xtraPath = path.substr(0, -3) + "xtra";
+			if( !sys.FileSystem.exists(xtraPath) )
+				xtraPath = null;
+			if( sys.FileSystem.exists(target) && sys.FileSystem.stat(target).mtime.getTime() >= sys.FileSystem.stat(path).mtime.getTime() && (xtraPath == null || sys.FileSystem.stat(target).mtime.getTime() >= sys.FileSystem.stat(xtraPath).mtime.getTime()) )
+				continue;
+			Sys.println(relPath);
+			var fbx = null;
+			try fbx = hxd.fmt.fbx.Parser.parse(sys.io.File.getContent(path)) catch( e : Dynamic ) throw Std.string(e) + " in " + relPath;
+			var hmdout = new hxd.fmt.fbx.HMDOut();
+			hmdout.load(fbx);
+			if( xtraPath != null )
+				hmdout.loadXtra(sys.io.File.getContent(xtraPath));
+			var hmd = hmdout.toHMD(null, !StringTools.startsWith(f, "Anim_"));
+			var out = new haxe.io.BytesOutput();
+			new hxd.fmt.hmd.Writer(out).write(hmd);
+			var bytes = out.getBytes();
+			sys.io.File.saveBytes(target, bytes);
+		}
+	}
+
 	static function main() {
-		hxd.Res.initEmbed({createHMD:true});
+		try sys.FileSystem.deleteFile("hxd.fmt.hmd.MakeAll.n") catch( e : Dynamic ) {}
+		if( !sys.FileSystem.exists("res") ) {
+			Sys.println("res directory not found");
+			Sys.exit(1);
+		}
+		loop("res");
 	}
 
 }