浏览代码

Added local params to convert (thanks Yuxiao) and added collide params in modelProps.

TothBenoit 3 周之前
父节点
当前提交
ea4586f996
共有 4 个文件被更改,包括 133 次插入65 次删除
  1. 43 24
      h3d/prim/ModelDatabase.hx
  2. 11 7
      hxd/fmt/fbx/HMDOut.hx
  3. 2 1
      hxd/fmt/hmd/Library.hx
  4. 77 33
      hxd/fs/Convert.hx

+ 43 - 24
h3d/prim/ModelDatabase.hx

@@ -1,12 +1,15 @@
 package h3d.prim;
 
+#if !macro
 typedef ModelDataInput = {
 	var resourceDirectory : String;
 	var resourceName : String;
 	var objectName : String;
 	var hmd : HMDModel;
 	var skin : h3d.scene.Skin;
+	var collide : Dynamic;
 }
+#end
 
 class ModelDatabase {
 
@@ -39,7 +42,16 @@ class ModelDatabase {
 		if( cached != null )
 			return cached;
 		var file = getFilePath(directory);
+		#if macro
+		if ( !haxe.io.Path.isAbsolute(file) )
+			file = haxe.macro.Context.definedValue("resourcesPath") + file;
+		var value = try haxe.Json.parse(sys.io.File.getBytes(file).toString()) catch( e : hxd.res.NotFound ) {};
+		#else
+		var fs = Std.downcast(hxd.res.Loader.currentInstance.fs, hxd.fs.LocalFileSystem);
+		if ( fs != null && haxe.io.Path.isAbsolute(file) )
+			file = file.substr(fs.baseDir.length);
 		var value = try haxe.Json.parse(hxd.res.Loader.currentInstance.load(file).toText()) catch( e : hxd.res.NotFound ) {};
+		#end
 		ModelDatabase.db.set(directory, value);
 		return value;
 	}
@@ -51,30 +63,6 @@ class ModelDatabase {
 		return Reflect.field(rootData, key);
 	}
 
-	function saveModelData( directory : String, resourceName : String, modelName : String, data : Dynamic ) {
-		var file = getFilePath(directory);
-
-		var rootData = getRootData(directory);
-		var key = resourceName + "/" + modelName;
-		if (data == null || Reflect.fields(data).length == 0)
-			Reflect.deleteField(rootData, key);
-		else
-			Reflect.setField(rootData, key, data);
-
-		#if ((sys || nodejs) && !usesys)
-		var fs = Std.downcast(hxd.res.Loader.currentInstance.fs, hxd.fs.LocalFileSystem);
-		if( fs != null && !haxe.io.Path.isAbsolute(file) )
-			file = fs.baseDir + file;
-		if( rootData == null || Reflect.fields(rootData).length == 0 )
-			(try sys.FileSystem.deleteFile(file) catch( e : Dynamic ) {});
-		else
-			sys.io.File.saveContent(file, haxe.Json.stringify(rootData, "\t"));
-		#else
-		throw "Can't save model props database " + file;
-		#end
-	}
-
-
 	// Used to clean previous version of modelDatabase, should be removed after some time
 	function cleanOldModelData( rootData : Dynamic, key : String) {
 		var oldKey = '${key}_LOD0';
@@ -106,6 +94,29 @@ class ModelDatabase {
 		}
 	}
 
+	#if !macro
+	function saveModelData( directory : String, resourceName : String, modelName : String, data : Dynamic ) {
+		var file = getFilePath(directory);
+
+		var rootData = getRootData(directory);
+		var key = resourceName + "/" + modelName;
+		if (data == null || Reflect.fields(data).length == 0)
+			Reflect.deleteField(rootData, key);
+		else
+			Reflect.setField(rootData, key, data);
+
+		#if ((sys || nodejs) && !usesys)
+		var fs = Std.downcast(hxd.res.Loader.currentInstance.fs, hxd.fs.LocalFileSystem);
+		if( fs != null && !haxe.io.Path.isAbsolute(file) )
+			file = fs.baseDir + file;
+		if( rootData == null || Reflect.fields(rootData).length == 0 )
+			(try sys.FileSystem.deleteFile(file) catch( e : Dynamic ) {});
+		else
+			sys.io.File.saveContent(file, haxe.Json.stringify(rootData, "\t"));
+		#else
+		throw "Can't save model props database " + file;
+		#end
+	}
 
 	function loadLodConfig( input : ModelDataInput, data : Dynamic ) {
 		var c = Reflect.field(data, LOD_CONFIG);
@@ -225,6 +236,12 @@ class ModelDatabase {
 		Reflect.setField(data, DYN_BONES_CONFIG, dynamicJoints);
 	}
 
+	function saveCollideConfig( input : ModelDataInput, data : Dynamic ) {
+		if ( !Reflect.hasField(input.collide, "collide") )
+			Reflect.deleteField(data, "collide");
+		else
+			Reflect.setField(data, "collide", Reflect.field(input.collide, "collide"));
+	}
 
 	public function loadModelProps( input : ModelDataInput ) {
 		var data : Dynamic = getModelData(input.resourceDirectory, input.resourceName, input.objectName);
@@ -242,9 +259,11 @@ class ModelDatabase {
 
 		saveLodConfig(input, data);
 		saveDynamicBonesConfig(input, data);
+		saveCollideConfig(input, data);
 
 		saveModelData(input.resourceDirectory, input.resourceName, input.objectName, data);
 	}
+	#end
 
 	public static var current = new ModelDatabase();
 }

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

@@ -22,6 +22,7 @@ class HMDOut extends BaseLibrary {
 	public var generateNormals = false;
 	public var generateTangents = false;
 	public var generateCollides : CollideParams;
+	public var modelCollides : Map<String, CollideParams> = [];
 	public var ignoreCollides : Array<String>;
 	var ignoreCollidesCache : Map<Int,Bool> = [];
 	public var lowPrecConfig : Map<String,Precision>;
@@ -814,13 +815,11 @@ class HMDOut extends BaseLibrary {
 		return { lodLevel : -1, modelName : null };
 	}
 
-	function buildColliders(g : hxd.fmt.hmd.Data, model : Model, geom : hxd.fmt.fbx.Geometry, bounds : h3d.col.Bounds) {
+	function buildColliders(g : hxd.fmt.hmd.Data, model : Model, geom : hxd.fmt.fbx.Geometry, bounds : h3d.col.Bounds, generateCollides : Dynamic ) {
 		var maxConvexHulls = generateCollides.maxConvexHulls;
 		var dim = bounds.dimension();
-		if ( dim <= generateCollides.precision )
-			return null;
-
-		var subdiv = Math.ceil(dim / generateCollides.precision);
+		var prec = Math.min(dim, generateCollides.precision);
+		var subdiv = Math.ceil(dim / prec);
 		subdiv = Math.imin(subdiv, generateCollides.maxSubdiv);
 		var maxResolution = subdiv * subdiv * subdiv;
 
@@ -1300,8 +1299,13 @@ class HMDOut extends BaseLibrary {
 				var geomData = new hxd.fmt.fbx.Geometry(this, g);
 
 				var geom = buildGeom(geomData, skin, dataOut, hasNormalMap || generateTangents);
-				if ( generateCollides != null )
-					buildColliders(d, model, geomData, geom.g.bounds);
+
+				if ( lodsInfos.lodLevel <= 0 ) {
+					var mname = model.getObjectName();
+					var collidersParams = modelCollides.exists(mname) ? modelCollides.get(mname) : generateCollides;
+					if ( collidersParams != null )
+						buildColliders(d, model, geomData, geom.g.bounds, collidersParams);
+				}
 
 				gdata = { gid : d.geometries.length, materials : geom.materials };
 				d.geometries.push(geom.g);

+ 2 - 1
hxd/fmt/hmd/Library.hx

@@ -473,7 +473,8 @@ class Library {
 				resourceName : resource.name,
 				objectName : obj.name,
 				hmd : Std.downcast(Std.downcast(obj, h3d.scene.Mesh)?.primitive, h3d.prim.HMDModel),
-				skin : Std.downcast(obj, h3d.scene.Skin)
+				skin : Std.downcast(obj, h3d.scene.Skin),
+				collide : null
 			}
 
 			// Apply default config to object (config that is in props.json)

+ 77 - 33
hxd/fs/Convert.hx

@@ -119,7 +119,22 @@ class ConvertFBX2HMD extends Convert {
 	}
 
 	override function hasLocalParams():Bool {
-		return (params != null && params.collide != null);
+		var filePath = srcPath.substring(srcPath.lastIndexOf("/") + 1);
+		var dirPath = srcPath.substring(0, srcPath.lastIndexOf("/"));
+		var modelPropsPath = dirPath + "/model.props";
+		var foundModelProps = false;
+		try {
+			var res = hxd.File.getBytes(modelPropsPath).toString();
+			var modelProps = haxe.Json.parse(res);
+			for( mp in Reflect.fields(modelProps) ) {
+				if( mp.substring(0, mp.lastIndexOf("/")) == filePath && Reflect.field(modelProps, mp).collide != null ) {
+					foundModelProps = true;
+					break;
+				}
+			}
+		} catch( e ) {
+		}
+		return (params != null && params.collide != null) || foundModelProps;
 	}
 
 	override function getLocalContext():Dynamic {
@@ -127,6 +142,29 @@ class ConvertFBX2HMD extends Convert {
 	}
 
 	override function computeLocalParams(context:Dynamic):Dynamic {
+		var filePath = srcPath.substring(srcPath.lastIndexOf("/") + 1);
+		var dirPath = srcPath.substring(0, srcPath.lastIndexOf("/"));
+		// Parse model.props to find model config
+		var modelCollides : Map<String, hxd.fmt.fbx.HMDOut.CollideParams> = [];
+		var modelPropsPath = dirPath + "/model.props";
+		var foundModelProps = false;
+		var modelProps = null;
+		try {
+			var res = hxd.File.getBytes(modelPropsPath).toString();
+			modelProps = haxe.Json.parse(res);
+		} catch( e ) {
+		}
+		if( modelProps != null ) {
+			for( mp in Reflect.fields(modelProps) ) {
+				var mpFile = mp.substring(0, mp.lastIndexOf("/"));
+				if( mpFile == filePath ) {
+					var mpModel = mp.substring(mp.lastIndexOf("/") + 1);
+					var collide = Reflect.field(modelProps, mp).collide;
+					modelCollides.set(mpModel, collide);
+					foundModelProps = true;
+				}
+			}
+		}
 		// Parse fbx to find used materials
 		if( context != null && context.matNames != null && Std.isOfType(context.matNames, Array) ) {
 			matNames = context.matNames;
@@ -142,8 +180,6 @@ class ConvertFBX2HMD extends Convert {
 		}
 		// Parse material.props to find material config
 		var ignoredMaterials = [];
-		var filePath = srcPath.substring(srcPath.lastIndexOf("/") + 1);
-		var dirPath = srcPath.substring(0, srcPath.lastIndexOf("/"));
 		var matPropsPath = dirPath + "/materials.props";
 		var matProps = null;
 		try {
@@ -151,43 +187,48 @@ class ConvertFBX2HMD extends Convert {
 			matProps = haxe.Json.parse(res).materials;
 		} catch( e ) {
 		}
-		if( matProps == null )
-			return null;
-		var modelLibCache = new Map<String, Array<Dynamic>>();
-		for( config in Reflect.fields(matProps) ) {
-			var configProps = Reflect.field(matProps, config);
-			for( matName in matNames ) {
-				var m = Reflect.field(configProps, matName + "/" + filePath);
-				if( m == null )
-					m = Reflect.field(configProps, matName);
-				if( m == null )
-					continue;
-				if( m.ignoreCollide == true ) {
-					ignoredMaterials.push(matName);
-					continue;
-				}
-				// Parse model library
-				if( m.__ref != null && m.name != null ) {
-					var libchildren = modelLibCache.get(m.__ref);
-					if( libchildren == null ) {
-						var lib = try haxe.Json.parse(hxd.File.getBytes(baseDir + m.__ref).toString()) catch( e ) null;
-						if( lib == null || lib.children == null )
-							continue;
-						libchildren = lib.children;
-						modelLibCache.set(m.__ref, libchildren);
+		if( matProps != null ) {
+			var modelLibCache = new Map<String, Array<Dynamic>>();
+			for( config in Reflect.fields(matProps) ) {
+				var configProps = Reflect.field(matProps, config);
+				for( matName in matNames ) {
+					var m = Reflect.field(configProps, matName + "/" + filePath);
+					if( m == null )
+						m = Reflect.field(configProps, matName);
+					if( m == null )
+						continue;
+					if( m.ignoreCollide == true ) {
+						ignoredMaterials.push(matName);
+						continue;
 					}
-					for( c in libchildren ) {
-						if( c.type == "material" && c.name == m.name ) {
-							if( c.props?.PBR?.ignoreCollide == true ) {
-								ignoredMaterials.push(matName);
+					// Parse model library
+					if( m.__ref != null && m.name != null ) {
+						var libchildren = modelLibCache.get(m.__ref);
+						if( libchildren == null ) {
+							var lib = try haxe.Json.parse(hxd.File.getBytes(baseDir + m.__ref).toString()) catch( e ) null;
+							if( lib == null || lib.children == null )
+								continue;
+							libchildren = lib.children;
+							modelLibCache.set(m.__ref, libchildren);
+						}
+						for( c in libchildren ) {
+							if( c.type == "material" && c.name == m.name ) {
+								if( c.props?.PBR?.ignoreCollide == true ) {
+									ignoredMaterials.push(matName);
+								}
+								break;
 							}
-							break;
 						}
 					}
 				}
 			}
 		}
-		return { ignoreCollideMaterials : ignoredMaterials };
+		var localParams = {};
+		if( ignoredMaterials.length > 0 )
+			Reflect.setField(localParams, "ignoreCollideMaterials", ignoredMaterials);
+		if( foundModelProps )
+			Reflect.setField(localParams, "modelCollides", modelCollides);
+		return localParams;
 	}
 
 	override function convert() {
@@ -235,6 +276,9 @@ class ConvertFBX2HMD extends Convert {
 			if( localParams.ignoreCollideMaterials != null ) {
 				hmdout.ignoreCollides = localParams.ignoreCollideMaterials;
 			}
+			if( localParams.modelCollides != null ) {
+				hmdout.modelCollides = localParams.modelCollides;
+			}
 		}
 		hmdout.load(fbx);
 		var isAnim = StringTools.startsWith(originalFilename, "Anim_") || originalFilename.toLowerCase().indexOf("_anim_") > 0;