2
0
Эх сурвалжийг харах

more SCN loading support, added shader dynamic loading

Nicolas Cannasse 8 жил өмнө
parent
commit
5158f90f6b

+ 3 - 0
bin/defaultProps.json

@@ -12,6 +12,9 @@
 	"key.redo" : "Ctrl-Y",
 	"key.redo" : "Ctrl-Y",
 	"key.save" : "Ctrl-S",
 	"key.save" : "Ctrl-S",
 
 
+	// paths to look files/shaders into - relative to project root
+	"haxe.classPath" : ["src"],
+
 	// reserved for internal ide usage
 	// reserved for internal ide usage
 	"hide" : {}
 	"hide" : {}
 
 

+ 1 - 0
hide.hxml

@@ -9,3 +9,4 @@
 -dce no
 -dce no
 --macro include('hide.view')
 --macro include('hide.view')
 --macro include('h3d.prim')
 --macro include('h3d.prim')
+--macro include('h3d.scene')

+ 1 - 1
hide.hxproj

@@ -24,7 +24,7 @@
     <option noInlineOnDebug="False" />
     <option noInlineOnDebug="False" />
     <option mainClass="hide.ui.Ide" />
     <option mainClass="hide.ui.Ide" />
     <option enabledebug="False" />
     <option enabledebug="False" />
-    <option additional="-lib hxnodejs&#xA;-lib heaps&#xA;-lib hxbit&#xA;-lib hscript&#xA;-D hscriptPos&#xA;-dce no&#xA;&#xA;--macro include('hide.view')&#xA;--macro include('h3d.prim')" />
+    <option additional="-lib hxnodejs&#xA;-lib heaps&#xA;-lib hxbit&#xA;-lib hscript&#xA;-D hscriptPos&#xA;-dce no&#xA;&#xA;--macro include('hide.view')&#xA;--macro include('h3d.prim')&#xA;--macro include('h3d.scene')" />
   </build>
   </build>
   <!-- haxelib libraries -->
   <!-- haxelib libraries -->
   <haxelib>
   <haxelib>

+ 9 - 0
hide/Macros.hx

@@ -11,6 +11,15 @@ class Macros {
 		return buildTypeDef(t);
 		return buildTypeDef(t);
 	}
 	}
 
 
+	public static macro function includeShaderSources() {
+		var path = Context.resolvePath("h3d/shader/BaseMesh.hx");
+		var dir = new haxe.io.Path(path).dir;
+		for( f in sys.FileSystem.readDirectory(dir) )
+			if( StringTools.endsWith(f,".hx") )
+				Context.addResource("shader/" + f.substr(0, -3), sys.io.File.getBytes(dir + "/" + f));
+		return macro null;
+	}
+
 	#if macro
 	#if macro
 
 
 	static function buildTypeDef( t : Type ) : Expr {
 	static function buildTypeDef( t : Type ) : Expr {

+ 88 - 2
hide/comp/Scene.hx

@@ -3,14 +3,19 @@ package hide.comp;
 @:access(hide.comp.Scene)
 @:access(hide.comp.Scene)
 class SceneLoader extends h3d.impl.Serializable.SceneSerializer {
 class SceneLoader extends h3d.impl.Serializable.SceneSerializer {
 
 
+	var ide : hide.ui.Ide;
 	var scnPath : String;
 	var scnPath : String;
 	var projectPath : String;
 	var projectPath : String;
 	var scene : Scene;
 	var scene : Scene;
+	var shaderPath : Array<String>;
+	var shaderCache = new Map<String, hxsl.SharedShader>();
 
 
-	public function new(scnPath,scene) {
+	public function new(scnPath, scene) {
+		ide = hide.ui.Ide.inst;
 		super();
 		super();
 		this.scnPath = scnPath;
 		this.scnPath = scnPath;
 		this.scene = scene;
 		this.scene = scene;
+		shaderPath = ide.currentProps.get("haxe.classPath");
 	}
 	}
 
 
 	override function initSCNPaths(resPath:String, projectPath:String) {
 	override function initSCNPaths(resPath:String, projectPath:String) {
@@ -18,6 +23,77 @@ class SceneLoader extends h3d.impl.Serializable.SceneSerializer {
 		this.projectPath = projectPath == null ? null : projectPath.split("\\").join("/");
 		this.projectPath = projectPath == null ? null : projectPath.split("\\").join("/");
 	}
 	}
 
 
+	override function loadShader(name:String) : hxsl.Shader {
+		var s = loadSharedShader(name);
+		if( s == null )
+			return null;
+		var sh = Type.createEmptyInstance(hxsl.Shader);
+		@:privateAccess {
+			sh.shader = s;
+			sh.constModified = true;
+		}
+		return sh;
+	}
+
+	function loadSharedShader( name : String ) {
+		var s = shaderCache.get(name);
+		if( s != null )
+			return s;
+		var e = loadShaderExpr(name);
+		if( e == null )
+			return null;
+		var chk = new hxsl.Checker();
+		chk.loadShader = function(iname) {
+			var e = loadShaderExpr(iname);
+			if( e == null )
+				throw "Could not @:import " + iname + " (referenced from " + name+")";
+			return e;
+		};
+		var s = new hxsl.SharedShader("");
+		s.data = chk.check(name, e);
+		@:privateAccess s.initialize();
+		shaderCache.set(name, s);
+		return s;
+	}
+
+	function loadShaderExpr( name : String ) : hxsl.Ast.Expr {
+		var path = name.split(".").join("/")+".hx";
+		for( s in shaderPath ) {
+			var file = ide.projectDir + "/" + s + "/" + path;
+			if( sys.FileSystem.exists(file) )
+				return loadShaderString(file,sys.io.File.getContent(file));
+		}
+		if( StringTools.startsWith(name,"h3d.shader.") ) {
+			var r = haxe.Resource.getString("shader/" + name.substr(11));
+			if( r != null ) return loadShaderString(path, r);
+		}
+		return null;
+	}
+
+	function loadShaderString( file : String, content : String ) {
+		var r = ~/var[ \t]+SRC[ \t]+=[ \t]+\{/;
+		if( !r.match(content) )
+			throw file+" does not contain shader SRC";
+		var src = r.matchedRight();
+		var count = 1;
+		var pos = 0;
+		while( pos < src.length ) {
+			switch( src.charCodeAt(pos++) ) {
+			case '{'.code: count++;
+			case '}'.code: count--; if( count == 0 ) break;
+			default:
+			}
+		}
+		src = src.substr(0, pos - 1);
+		var parser = new hscript.Parser();
+		parser.allowTypes = true;
+		parser.allowMetadata = true;
+		parser.line = r.matchedLeft().split("\n").length;
+		var e = parser.parseString(src, file);
+		var e = new hscript.Macro({ min : 0, max : 0, file : file }).convert(e);
+		return new hxsl.MacroParser().parseExpr(e);
+	}
+
 	override function loadHMD(path:String) {
 	override function loadHMD(path:String) {
 		var path = resolvePath(path);
 		var path = resolvePath(path);
 		if( path == null )
 		if( path == null )
@@ -51,6 +127,7 @@ class Scene extends Component implements h3d.IDrawable {
 	var stage : hxd.Stage;
 	var stage : hxd.Stage;
 	var canvas : js.html.CanvasElement;
 	var canvas : js.html.CanvasElement;
 	var engine : h3d.Engine;
 	var engine : h3d.Engine;
+	var hmdCache = new Map<String, hxd.fmt.hmd.Library>();
 	public var s2d : h2d.Scene;
 	public var s2d : h2d.Scene;
 	public var s3d : h3d.scene.Scene;
 	public var s3d : h3d.scene.Scene;
 	public var sevents : hxd.SceneEvents;
 	public var sevents : hxd.SceneEvents;
@@ -149,6 +226,7 @@ class Scene extends Component implements h3d.IDrawable {
 	function initMaterials( obj : h3d.scene.Object, path : String ) {
 	function initMaterials( obj : h3d.scene.Object, path : String ) {
 		var res = hxd.res.Any.fromBytes(path, haxe.io.Bytes.alloc(0));
 		var res = hxd.res.Any.fromBytes(path, haxe.io.Bytes.alloc(0));
 		for( m in obj.getMaterials() ) {
 		for( m in obj.getMaterials() ) {
+			if( m.name == null ) continue;
 			m.model = res;
 			m.model = res;
 			h3d.mat.MaterialSetup.current.initModelMaterial(m);
 			h3d.mat.MaterialSetup.current.initModelMaterial(m);
 		}
 		}
@@ -219,6 +297,12 @@ class Scene extends Component implements h3d.IDrawable {
 
 
 	function loadHMD( path : String, isAnimation : Bool ) {
 	function loadHMD( path : String, isAnimation : Bool ) {
 		var fullPath = ide.getPath(path);
 		var fullPath = ide.getPath(path);
+		var hmd = hmdCache.get(fullPath);
+
+		if( hmd != null )
+			return hmd;
+		trace(fullPath);
+
 		var data = sys.io.File.getBytes(fullPath);
 		var data = sys.io.File.getBytes(fullPath);
 		if( data.get(0) != 'H'.code ) {
 		if( data.get(0) != 'H'.code ) {
 			var hmdOut = new hxd.fmt.fbx.HMDOut();
 			var hmdOut = new hxd.fmt.fbx.HMDOut();
@@ -229,7 +313,9 @@ class Scene extends Component implements h3d.IDrawable {
 			new hxd.fmt.hmd.Writer(out).write(hmd);
 			new hxd.fmt.hmd.Writer(out).write(hmd);
 			data = out.getBytes();
 			data = out.getBytes();
 		}
 		}
-		return hxd.res.Any.fromBytes(path,data).toModel().toHmd();
+		hmd = hxd.res.Any.fromBytes(path, data).toModel().toHmd();
+		hmdCache.set(fullPath, hmd);
+		return hmd;
 	}
 	}
 
 
 	public function resetCamera( ?obj : h3d.scene.Object, distanceFactor = 1. ) {
 	public function resetCamera( ?obj : h3d.scene.Object, distanceFactor = 1. ) {

+ 1 - 0
hide/ui/Ide.hx

@@ -441,6 +441,7 @@ class Ide {
 	public static var inst : Ide;
 	public static var inst : Ide;
 
 
 	static function main() {
 	static function main() {
+		Macros.includeShaderSources();
 		new Ide();
 		new Ide();
 	}
 	}