瀏覽代碼

default material props storage policy

Nicolas Cannasse 8 年之前
父節點
當前提交
69ca6815a3
共有 3 個文件被更改,包括 80 次插入6 次删除
  1. 2 1
      h3d/mat/Material.hx
  2. 74 3
      h3d/mat/MaterialSetup.hx
  3. 4 2
      h3d/prim/ModelCache.hx

+ 2 - 1
h3d/mat/Material.hx

@@ -4,7 +4,8 @@ class Material extends BaseMaterial {
 
 	var mshader : h3d.shader.BaseMesh;
 
-	public var props(default,set) : Any;
+	public var props(default, set) : Any;
+	public var model : hxd.res.Resource;
 
 	public var shadows(get, set) : Bool;
 	public var castShadows(default, set) : Bool;

+ 74 - 3
h3d/mat/MaterialSetup.hx

@@ -31,9 +31,74 @@ class MaterialSetup {
 		return new h3d.pass.LightSystem();
 	}
 
-	public function initModelMaterial( model : hxd.res.Model, material : Material ) {
-		material.mainPass.enableLights = true;
-		material.shadows = true;
+	public function initModelMaterial( material : Material ) {
+		var props = getStoredProps(getMaterialDBPath(material));
+		if( props == null ) props = getDefaults();
+		material.props = props;
+	}
+
+	function getMaterialDBPath( material : Material ) {
+		var path = material.model.entry.path.split("/");
+		path.pop();
+		path.push(material.name);
+		path.unshift(name);
+		return path;
+	}
+
+	public function saveModelMaterial( material : Material ) {
+		if( materialDB == null ) loadDB();
+		var path = getMaterialDBPath(material);
+		var root : Dynamic = materialDB;
+		var prevs = [];
+		for( i in 0...path.length - 1 ) {
+			var next = Reflect.field(root, path[i]);
+			if( next == null ) {
+				next = {};
+				Reflect.setField(root, path[i], next);
+			}
+			prevs.push(root);
+			root = next;
+		}
+		var name = path.pop();
+		Reflect.deleteField(root, name);
+
+		var currentProps = material.props;
+		initModelMaterial(material); // reset to default
+		if( Std.string(material.props) == Std.string(currentProps) ) {
+			// cleanup
+			while( path.length > 0 ) {
+				var name = path.pop();
+				var root = prevs.pop();
+				if( Reflect.fields(Reflect.field(root, name)).length != 0 )
+					break;
+				Reflect.deleteField(root, name);
+			}
+		} else {
+			Reflect.setField(root, name, currentProps);
+			material.props = currentProps;
+		}
+		saveDB();
+	}
+
+	function saveDB() {
+		#if sys
+		var path = haxe.macro.Compiler.getDefine("resourcesPath");
+		if( path == null ) path = "res";
+		sys.io.File.saveContent(path + "/" + dbPath, haxe.Json.stringify(materialDB, "\t"));
+		#else
+		throw "Can't save material props database " + dbPath;
+		#end
+	}
+
+	function getStoredProps( path : Array<String> ) {
+		if( materialDB == null ) loadDB();
+		var root : Dynamic = materialDB;
+		while( path.length > 0 ) {
+			root = Reflect.field(root, path.shift());
+			if( root == null )
+				return null;
+		}
+		return root;
 	}
 
 	public function getDefaults( ?type : String ) : Any {
@@ -113,4 +178,10 @@ class MaterialSetup {
 
 	public static var current = new MaterialSetup("Default");
 
+	static var dbPath = "materials.json";
+	static var materialDB : Dynamic;
+	static function loadDB() {
+		materialDB = try haxe.Json.parse(hxd.res.Loader.currentInstance.load(dbPath).toText()) catch( e : hxd.res.NotFound ) {};
+	}
+
 }

+ 4 - 2
h3d/prim/ModelCache.hx

@@ -32,8 +32,10 @@ class ModelCache {
 
 	public function loadModel( res : hxd.res.Model ) : h3d.scene.Object {
 		var obj = loadLibrary(res).makeObject(loadTexture.bind(res));
-		for( m in obj.getMaterials() )
-			h3d.mat.MaterialSetup.current.initModelMaterial(res, Std.instance(m, h3d.mat.Material));
+		for( m in obj.getMaterials() ) {
+			m.model = res;
+			h3d.mat.MaterialSetup.current.initModelMaterial(m);
+		}
 		return obj;
 	}