浏览代码

moved prefab definition from heaps to hrt

ncannasse 6 年之前
父节点
当前提交
99dbea31ef
共有 54 个文件被更改,包括 1204 次插入108 次删除
  1. 5 5
      hide/Ide.hx
  2. 17 17
      hide/comp/SceneEditor.hx
  3. 2 2
      hide/prefab/ContextShared.hx
  4. 2 2
      hide/prefab/EditContext.hx
  5. 3 3
      hide/prefab/HideProps.hx
  6. 1 1
      hide/prefab/PolygonEditor.hx
  7. 1 1
      hide/prefab/terrain/Brush.hx
  8. 1 1
      hide/prefab/terrain/TerrainEditor.hx
  9. 2 2
      hide/view/FXEditor.hx
  10. 1 1
      hide/view/FileTree.hx
  11. 4 4
      hide/view/Model.hx
  12. 4 4
      hide/view/Prefab.hx
  13. 4 4
      hide/view/l3d/Level3D.hx
  14. 5 5
      hide/view/l3d/LightProbeBaker.hx
  15. 1 1
      hide/view/l3d/ProbeBakerProcess.hx
  16. 1 1
      hrt/prefab/Blur.hx
  17. 1 1
      hrt/prefab/Box.hx
  18. 1 1
      hrt/prefab/Constraint.hx
  19. 86 0
      hrt/prefab/Context.hx
  20. 237 0
      hrt/prefab/ContextShared.hx
  21. 1 1
      hrt/prefab/Curve.hx
  22. 77 0
      hrt/prefab/Library.hx
  23. 1 1
      hrt/prefab/Light.hx
  24. 3 4
      hrt/prefab/Material.hx
  25. 2 2
      hrt/prefab/Model.hx
  26. 1 1
      hrt/prefab/Noise.hx
  27. 1 1
      hrt/prefab/Object3D.hx
  28. 413 0
      hrt/prefab/Prefab.hx
  29. 3 3
      hrt/prefab/Reference.hx
  30. 3 3
      hrt/prefab/RenderProps.hx
  31. 1 1
      hrt/prefab/Scene.hx
  32. 1 1
      hrt/prefab/Settings.hx
  33. 2 2
      hrt/prefab/Shader.hx
  34. 1 1
      hrt/prefab/Trail.hx
  35. 26 0
      hrt/prefab/Unknown.hx
  36. 1 1
      hrt/prefab/fx/AnimEvent.hx
  37. 2 2
      hrt/prefab/fx/Emitter.hx
  38. 1 1
      hrt/prefab/fx/Event.hx
  39. 3 3
      hrt/prefab/fx/FX.hx
  40. 2 2
      hrt/prefab/fx/LookAt.hx
  41. 0 2
      hrt/prefab/import.hx
  42. 1 1
      hrt/prefab/l3d/AdvancedDecal.hx
  43. 2 2
      hrt/prefab/l3d/Camera.hx
  44. 1 1
      hrt/prefab/l3d/Decal.hx
  45. 3 3
      hrt/prefab/l3d/Instance.hx
  46. 6 9
      hrt/prefab/l3d/Level3D.hx
  47. 1 1
      hrt/prefab/l3d/MeshGenerator.hx
  48. 1 1
      hrt/prefab/l3d/Polygon.hx
  49. 1 1
      hrt/prefab/l3d/VolumetricLightmap.hx
  50. 71 0
      hrt/prefab/rfx/Bloom.hx
  51. 82 0
      hrt/prefab/rfx/DistanceFog.hx
  52. 24 0
      hrt/prefab/rfx/RendererFX.hx
  53. 86 0
      hrt/prefab/rfx/Sao.hx
  54. 1 1
      hrt/prefab/terrain/Terrain.hx

+ 5 - 5
hide/Ide.hx

@@ -645,10 +645,10 @@ class Ide {
 		return str;
 	}
 
-	public function loadPrefab<T:hxd.prefab.Prefab>( file : String, ?cl : Class<T> ) : T {
+	public function loadPrefab<T:hrt.prefab.Prefab>( file : String, ?cl : Class<T> ) : T {
 		if( file == null )
 			return null;
-		var l = hxd.prefab.Library.create(file.split(".").pop().toLowerCase());
+		var l = hrt.prefab.Library.create(file.split(".").pop().toLowerCase());
 		try {
 			l.loadData(parseJSON(sys.io.File.getContent(getPath(file))));
 		} catch( e : Dynamic ) {
@@ -660,13 +660,13 @@ class Ide {
 		return l.get(cl);
 	}
 
-	public function savePrefab( file : String, f : hxd.prefab.Prefab ) {
+	public function savePrefab( file : String, f : hrt.prefab.Prefab ) {
 		var content = f.saveData();
 		sys.io.File.saveContent(getPath(file), toJSON(content));
 	}
 
-	public function filterPrefabs( callb : hxd.prefab.Prefab -> Bool ) {
-		var exts = Lambda.array({iterator : @:privateAccess hxd.prefab.Library.registeredExtensions.keys });
+	public function filterPrefabs( callb : hrt.prefab.Prefab -> Bool ) {
+		var exts = Lambda.array({iterator : @:privateAccess hrt.prefab.Library.registeredExtensions.keys });
 		exts.push("prefab");
 		var todo = [];
 		browseFiles(function(path) {

+ 17 - 17
hide/comp/SceneEditor.hx

@@ -3,7 +3,7 @@ package hide.comp;
 import hxd.Key as K;
 import hxd.Math as M;
 
-import hxd.prefab.Prefab as PrefabElement;
+import hrt.prefab.Prefab as PrefabElement;
 import hrt.prefab.Object3D;
 import h3d.scene.Object;
 
@@ -38,12 +38,12 @@ class SceneEditorContext extends hide.prefab.EditContext {
 		}
 	}
 
-	override function getCurrentProps( p : hxd.prefab.Prefab ) {
+	override function getCurrentProps( p : hrt.prefab.Prefab ) {
 		var cur = editor.curEdit;
 		return cur != null && cur.elements[0] == p ? editor.properties.element : new Element();
 	}
 
-	function getContextRec( p : hxd.prefab.Prefab ) {
+	function getContextRec( p : hrt.prefab.Prefab ) {
 		if( p == null )
 			return editor.context;
 		var c = editor.context.shared.contexts.get(p);
@@ -57,7 +57,7 @@ class SceneEditorContext extends hide.prefab.EditContext {
 		editor.selectObjects(elements);
 	}
 
-	override function rebuildPrefab( p : hxd.prefab.Prefab ) {
+	override function rebuildPrefab( p : hrt.prefab.Prefab ) {
 		// refresh all for now
 		editor.refresh();
 	}
@@ -85,7 +85,7 @@ class SceneEditor {
 	public var favTree : hide.comp.IconTree<PrefabElement>;
 	public var scene : hide.comp.Scene;
 	public var properties : hide.comp.PropsEditor;
-	public var context(default,null) : hxd.prefab.Context;
+	public var context(default,null) : hrt.prefab.Context;
 	public var curEdit(default, null) : SceneEditorContext;
 	public var snapToGround = false;
 	public var localTransform = true;
@@ -137,7 +137,7 @@ class SceneEditor {
 			onResize();
 		};
 
-		context = new hxd.prefab.Context();
+		context = new hrt.prefab.Context();
 		context.shared = new hide.prefab.ContextShared(scene);
 		context.shared.currentPath = view.state.path;
 		context.init();
@@ -183,7 +183,7 @@ class SceneEditor {
 
 		// Load display state
 		{
-			var all = sceneData.flatten(hxd.prefab.Prefab);
+			var all = sceneData.flatten(hrt.prefab.Prefab);
 			var list = @:privateAccess view.getDisplayState("hideList");
 			if(list != null) {
 				var m = [for(i in (list:Array<Dynamic>)) i => true];
@@ -413,7 +413,7 @@ class SceneEditor {
 
 	function refreshTree( ?callb ) {
 		tree.refresh(function() {
-			var all = sceneData.flatten(hxd.prefab.Prefab);
+			var all = sceneData.flatten(hrt.prefab.Prefab);
 			for(elt in all) {
 				var el = tree.getElement(elt);
 				if(el == null) continue;
@@ -452,7 +452,7 @@ class SceneEditor {
 		scene.engine.backgroundColor = bgcol;
 		refreshInteractives();
 
-		var all = sceneData.flatten(hxd.prefab.Prefab);
+		var all = sceneData.flatten(hrt.prefab.Prefab);
 		for(elt in all)
 			applySceneStyle(elt);
 		onRefresh();
@@ -934,7 +934,7 @@ class SceneEditor {
 		fillProps(edit, e);
 	}
 
-	function setObjectSelected( p : PrefabElement, ctx : hxd.prefab.Context, b : Bool ) {
+	function setObjectSelected( p : PrefabElement, ctx : hrt.prefab.Context, b : Bool ) {
 		p.setSelected(ctx, b);
 	}
 
@@ -976,7 +976,7 @@ class SceneEditor {
 		setupGizmo();
 	}
 
-	function hasBeenRemoved( e : hxd.prefab.Prefab ) {
+	function hasBeenRemoved( e : hrt.prefab.Prefab ) {
 		while( e != null && e != sceneData ) {
 			if( e.parent != null && e.parent.children.indexOf(e) < 0 )
 				return true;
@@ -1022,7 +1022,7 @@ class SceneEditor {
 			var obj3d : Object3D;
 			var relative = ide.makeRelative(path);
 
-			if(hxd.prefab.Library.getPrefabType(path) != null) {
+			if(hrt.prefab.Library.getPrefabType(path) != null) {
 				var ref = new hrt.prefab.Reference(parent);
 				ref.refpath = "/" + relative;
 				obj3d = ref;
@@ -1143,7 +1143,7 @@ class SceneEditor {
 			view.setClipboard(curEdit.rootElements[0].saveData(), "prefab");
 		}
 		else {
-			var lib = new hxd.prefab.Library();
+			var lib = new hrt.prefab.Library();
 			for(e in curEdit.rootElements) {
 				lib.children.push(e);
 			}
@@ -1158,14 +1158,14 @@ class SceneEditor {
 		}
 		var obj = haxe.Json.parse(haxe.Json.stringify(view.getClipboard("prefab")));
 		if(obj != null) {
-			var p = hxd.prefab.Prefab.loadPrefab(obj, parent);
+			var p = hrt.prefab.Prefab.loadPrefab(obj, parent);
 			autoName(p);
 			refresh();
 		}
 		else {
 			obj = view.getClipboard("library");
 			if(obj != null) {
-				var lib = hxd.prefab.Prefab.loadPrefab(obj);
+				var lib = hrt.prefab.Prefab.loadPrefab(obj);
 				for(c in lib.children) {
 					autoName(c);
 					c.parent = parent;
@@ -1581,7 +1581,7 @@ class SceneEditor {
 	// Override
 	function getNewContextMenu(current: PrefabElement, ?onMake: PrefabElement->Void=null) : Array<hide.comp.ContextMenu.ContextMenuItem> {
 		var newItems = new Array<hide.comp.ContextMenu.ContextMenuItem>();
-		var allRegs = hxd.prefab.Library.getRegistered().copy();
+		var allRegs = hrt.prefab.Library.getRegistered().copy();
 		allRegs.remove("reference");
 		var parent = current == null ? sceneData : current;
 		var allowChildren = null;
@@ -1611,7 +1611,7 @@ class SceneEditor {
 	}
 
 	function getNewTypeMenuItem(ptype: String, parent: PrefabElement, onMake: PrefabElement->Void, ?label: String) : hide.comp.ContextMenu.ContextMenuItem {
-		var pmodel = hxd.prefab.Library.getRegistered().get(ptype);
+		var pmodel = hrt.prefab.Library.getRegistered().get(ptype);
 		return {
 			label : label != null ? label : pmodel.inf.name,
 			click : function() {

+ 2 - 2
hide/prefab/ContextShared.hx

@@ -1,6 +1,6 @@
 package hide.prefab;
 
-class ContextShared extends hxd.prefab.ContextShared {
+class ContextShared extends hrt.prefab.ContextShared {
 	#if editor
 	var scene : hide.comp.Scene;
 
@@ -17,7 +17,7 @@ class ContextShared extends hxd.prefab.ContextShared {
 		hide.Ide.inst.error(e);
 	}
 
-	override function loadPrefab( path : String ) : hxd.prefab.Prefab {
+	override function loadPrefab( path : String ) : hrt.prefab.Prefab {
 		return hide.Ide.inst.loadPrefab(path);
 	}
 

+ 2 - 2
hide/prefab/EditContext.hx

@@ -1,6 +1,6 @@
 package hide.prefab;
-import hxd.prefab.Prefab;
-import hxd.prefab.Context;
+import hrt.prefab.Prefab;
+import hrt.prefab.Context;
 
 class EditContext {
 

+ 3 - 3
hide/prefab/HideProps.hx

@@ -5,8 +5,8 @@ typedef HideProps = {
 	var name : String;
 	@:optional var fileSource : Array<String>;
 	@:optional dynamic function allowChildren( type : String ) : Bool;
-	@:optional dynamic function allowParent( p : hxd.prefab.Prefab ) : Bool;
-	@:optional dynamic function onChildUpdate( p : hxd.prefab.Prefab ) : Void;
-	@:optional dynamic function onChildRemoved( p : hxd.prefab.Prefab ) : Void;
+	@:optional dynamic function allowParent( p : hrt.prefab.Prefab ) : Bool;
+	@:optional dynamic function onChildUpdate( p : hrt.prefab.Prefab ) : Void;
+	@:optional dynamic function onChildRemoved( p : hrt.prefab.Prefab ) : Void;
 	@:optional dynamic function onResourceRenamed( map : (oldPath : String) -> String ) : Void;
 }

+ 1 - 1
hide/prefab/PolygonEditor.hx

@@ -1,6 +1,6 @@
 package hide.prefab;
 import hxd.Key as K;
-import hxd.prefab.Context;
+import hrt.prefab.Context;
 
 enum ColorState{
 	None;

+ 1 - 1
hide/prefab/terrain/Brush.hx

@@ -81,7 +81,7 @@ class BrushPreview {
 			tile.remove();
 	}
 
-	public function addPreviewMeshAt(x : Int, y : Int, brush : Brush, brushPos : h3d.Vector, ctx : hxd.prefab.Context) : TilePreviewMesh {
+	public function addPreviewMeshAt(x : Int, y : Int, brush : Brush, brushPos : h3d.Vector, ctx : hrt.prefab.Context) : TilePreviewMesh {
 		var camera = @:privateAccess ctx.local3d.getScene().camera;
 		var dir = camera.pos.sub(new h3d.Vector(terrain.getAbsPos().tx, terrain.getAbsPos().ty, terrain.getAbsPos().tz));
 		var offsetDir = dir.z < 0 ? -1: 1;

+ 1 - 1
hide/prefab/terrain/TerrainEditor.hx

@@ -2,7 +2,7 @@ package hide.prefab.terrain;
 
 using Lambda;
 import hxd.Key as K;
-import hxd.prefab.Context;
+import hrt.prefab.Context;
 
 enum RenderMode {
 	PBR;

+ 2 - 2
hide/view/FXEditor.hx

@@ -2,7 +2,7 @@ package hide.view;
 using Lambda;
 
 import hide.Element;
-import hxd.prefab.Prefab in PrefabElement;
+import hrt.prefab.Prefab in PrefabElement;
 import hrt.prefab.Curve;
 import hrt.prefab.fx.Event;
 
@@ -48,7 +48,7 @@ private class FXSceneEditor extends hide.comp.SceneEditor {
 		parent.onUpdate(dt);
 	}
 
-	override function setObjectSelected( p : PrefabElement, ctx : hxd.prefab.Context, b : Bool ) {
+	override function setObjectSelected( p : PrefabElement, ctx : hrt.prefab.Context, b : Bool ) {
 		if( p.getParent(hrt.prefab.fx.Emitter) != null )
 			return;
 		super.setObjectSelected(p, ctx, b);

+ 1 - 1
hide/view/FileTree.hx

@@ -176,7 +176,7 @@ class FileTree extends FileView {
 		var isDir = sys.FileSystem.isDirectory(ide.getPath(path));
 		if( isDir )
 			throw "TODO : rename directory";
-		ide.filterPrefabs(function(p:hxd.prefab.Prefab) {
+		ide.filterPrefabs(function(p:hrt.prefab.Prefab) {
 			var changed = false;
 			function filter(p:String) {
 				if( p == null )

+ 4 - 4
hide/view/Model.hx

@@ -10,7 +10,7 @@ class Model extends FileView {
 	var overlay : Element;
 	var eventList : Element;
 
-	var plight : hxd.prefab.Prefab;
+	var plight : hrt.prefab.Prefab;
 	var light : h3d.scene.Object;
 	var lightDirection : h3d.Vector;
 
@@ -24,7 +24,7 @@ class Model extends FileView {
 	var cameraMove : Void -> Void;
 	var scene(get,never) : hide.comp.Scene;
 	var rootPath : String;
-	var root : hxd.prefab.Prefab;
+	var root : hrt.prefab.Prefab;
 
 	override function save() {
 		if(!modified) return;
@@ -107,10 +107,10 @@ class Model extends FileView {
 			rootPath = config.get("scene.renderProps");
 
 		if( rootPath != null )
-			root = ide.loadPrefab(rootPath, hxd.prefab.Library);
+			root = ide.loadPrefab(rootPath, hrt.prefab.Library);
 
 		if( root == null ) {
-			var def = new hxd.prefab.Library();
+			var def = new hrt.prefab.Library();
 			new hrt.prefab.RenderProps(def).name = "renderer";
 			var l = new hrt.prefab.Light(def);
 			l.name = "sunLight";

+ 4 - 4
hide/view/Prefab.hx

@@ -1,6 +1,6 @@
 package hide.view;
 
-import hxd.prefab.Prefab in PrefabElement;
+import hrt.prefab.Prefab in PrefabElement;
 
 @:access(hide.view.Prefab)
 private class PrefabSceneEditor extends hide.comp.SceneEditor {
@@ -26,7 +26,7 @@ private class PrefabSceneEditor extends hide.comp.SceneEditor {
 class Prefab extends FileView {
 
 	var sceneEditor : PrefabSceneEditor;
-	var data : hxd.prefab.Library;
+	var data : hrt.prefab.Library;
 	var tabs : hide.comp.Tabs;
 
 	var tools : hide.comp.Toolbar;
@@ -46,7 +46,7 @@ class Prefab extends FileView {
 	var currentSign : String;
 
 	override function getDefaultContent() {
-		return haxe.io.Bytes.ofString(ide.toJSON(new hxd.prefab.Library().saveData()));
+		return haxe.io.Bytes.ofString(ide.toJSON(new hrt.prefab.Library().saveData()));
 	}
 
 	override function onFileChanged(wasDeleted:Bool) {
@@ -69,7 +69,7 @@ class Prefab extends FileView {
 
 	override function onDisplay() {
 		saveDisplayKey = "Prefab:" + getPath().split("\\").join("/").substr(0,-1);
-		data = new hxd.prefab.Library();
+		data = new hrt.prefab.Library();
 		var content = sys.io.File.getContent(getPath());
 		data.loadData(haxe.Json.parse(content));
 		currentSign = haxe.crypto.Md5.encode(content);

+ 4 - 4
hide/view/l3d/Level3D.hx

@@ -4,7 +4,7 @@ using Lambda;
 import hxd.Math;
 import hxd.Key as K;
 
-import hxd.prefab.Prefab as PrefabElement;
+import hrt.prefab.Prefab as PrefabElement;
 import hrt.prefab.Object3D;
 import hrt.prefab.l3d.Instance;
 import h3d.scene.Object;
@@ -432,7 +432,7 @@ class Level3D extends FileView {
 		for( p in passes )
 			p.isStatic = true;
 
-		function isDynamic(elt: hxd.prefab.Prefab) {
+		function isDynamic(elt: hrt.prefab.Prefab) {
 			var p = elt;
 			while(p != null) {
 				if(p.name == "dynamic")
@@ -609,7 +609,7 @@ class Level3D extends FileView {
 
 	function applySceneFilter(typeid: String, visible: Bool) {
 		saveDisplayState("sceneFilters/" + typeid, visible);
-		var all = data.flatten(hxd.prefab.Prefab);
+		var all = data.flatten(hrt.prefab.Prefab);
 		for(p in all) {
 			if(p.type == typeid || getCdbTypeId(p) == typeid) {
 				sceneEditor.applySceneStyle(p);
@@ -749,7 +749,7 @@ class Level3D extends FileView {
 		}
 	}
 
-	public static function getCdbModel(e:hxd.prefab.Prefab):cdb.Sheet {
+	public static function getCdbModel(e:hrt.prefab.Prefab):cdb.Sheet {
 		var typeName : String = getCdbTypeId(e);
 		if(typeName == null)
 			return null;

+ 5 - 5
hide/view/l3d/LightProbeBaker.hx

@@ -7,7 +7,7 @@ class LightProbeBaker {
 	public var useGPU = false;
 	public var environment : h3d.scene.pbr.Environment;
 
-	var context : hxd.prefab.Context;
+	var context : hrt.prefab.Context;
 	var offScreenScene : h3d.scene.Scene = null;
 	var prim : h3d.prim.Plane2D;
 
@@ -38,7 +38,7 @@ class LightProbeBaker {
 		customCamera.screenRatio = 1.0;
 		customCamera.fovY = 90;
 		customCamera.zFar = 100;
-		context = new hxd.prefab.Context();
+		context = new hrt.prefab.Context();
 	}
 
 	public function dispose() {
@@ -58,7 +58,7 @@ class LightProbeBaker {
 		if(offScreenScene != null) offScreenScene.dispose();
 	}
 
-	public function initScene( sceneData : hxd.prefab.Prefab, shared : hide.prefab.ContextShared, scene : hide.comp.Scene , env : h3d.scene.pbr.Environment) {
+	public function initScene( sceneData : hrt.prefab.Prefab, shared : hide.prefab.ContextShared, scene : hide.comp.Scene , env : h3d.scene.pbr.Environment) {
 		if(offScreenScene != null) offScreenScene.dispose();
 		offScreenScene = new h3d.scene.Scene();
 
@@ -70,12 +70,12 @@ class LightProbeBaker {
 		context.local3d = offScreenScene;
 
 		var whiteList = [ "level3d", "object", "model", "material", "light"];
-		function keep( p : hxd.prefab.Prefab ) {
+		function keep( p : hrt.prefab.Prefab ) {
 			for( f in whiteList )
 				if( f == p.type ) return true;
 			return false;
 		}
-		function filter( p : hxd.prefab.Prefab ) {
+		function filter( p : hrt.prefab.Prefab ) {
 			for( c in p.children ) {
 				if(!keep(c))
 					sceneData.children.remove(c);

+ 1 - 1
hide/view/l3d/ProbeBakerProcess.hx

@@ -18,7 +18,7 @@ class ProbeBakerProcess {
 		lightProbeBaker.useGPU = useGPU;
 	}
 
-	public function init( env : h3d.scene.pbr.Environment, sceneData : hxd.prefab.Prefab , shared : hide.prefab.ContextShared, scene : hide.comp.Scene) {
+	public function init( env : h3d.scene.pbr.Environment, sceneData : hrt.prefab.Prefab , shared : hide.prefab.ContextShared, scene : hide.comp.Scene) {
 		lightProbeBaker.initScene(sceneData, shared, scene, env);
 	}
 

+ 1 - 1
hrt/prefab/Blur.hx

@@ -116,6 +116,6 @@ class Blur extends Prefab {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("blur", Blur);
+	static var _ = Library.register("blur", Blur);
 
 }

+ 1 - 1
hrt/prefab/Box.hx

@@ -66,5 +66,5 @@ class Box extends Object3D {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("box", Box);
+	static var _ = Library.register("box", Box);
 }

+ 1 - 1
hrt/prefab/Constraint.hx

@@ -69,6 +69,6 @@ class Constraint extends Prefab {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("constraint", Constraint);
+	static var _ = Library.register("constraint", Constraint);
 
 }

+ 86 - 0
hrt/prefab/Context.hx

@@ -0,0 +1,86 @@
+package hrt.prefab;
+
+@:final class Context {
+
+	public var local2d : h2d.Object;
+	public var local3d : h3d.scene.Object;
+	public var shared : ContextShared;
+	public var cleanup : Void -> Void;
+	public var custom : Dynamic;
+	public var isRef : Bool = false;
+
+	public function new() {
+	}
+
+	public function init() {
+		if( shared == null )
+			shared = new ContextShared();
+		local2d = shared.root2d;
+		local3d = shared.root3d;
+	}
+
+	public function clone( p : Prefab ) {
+		var c = new Context();
+		c.shared = shared;
+		c.local2d = local2d;
+		c.local3d = local3d;
+		c.custom = custom;
+		c.isRef = isRef;
+		if( p != null ) {
+			if(!isRef)
+				shared.contexts.set(p, c);
+			else {
+				if(!shared.references.exists(p))
+					shared.references.set(p, [c])
+				else
+					shared.references[p].push(c);
+			}
+		}
+		return c;
+	}
+
+	public function loadModel( path : String ) {
+		return shared.loadModel(path);
+	}
+
+	public function loadAnimation( path : String ) {
+		return shared.loadAnimation(path);
+	}
+
+	public function loadTexture( path : String ) {
+		return shared.loadTexture(path);
+	}
+
+	public function loadShader( name : String ) {
+		return shared.loadShader(name);
+	}
+
+	public function locateObject( path : String ) {
+		if( path == null )
+			return null;
+		var parts = path.split(".");
+		var root = shared.root3d;
+		while( parts.length > 0 ) {
+			var v = null;
+			var pname = parts.shift();
+			for( o in root )
+				if( o.name == pname ) {
+					v = o;
+					break;
+				}
+			if( v == null ) {
+				v = root.getObjectByName(pname);
+				//if( v != null && v.parent != root ) v = null; ??
+			}
+			if( v == null ) {
+				var parts2 = path.split(".");
+				for( i in 0...parts.length ) parts2.pop();
+				shared.onError("Object not found " + parts2.join("."));
+				return null;
+			}
+			root = v;
+		}
+		return root;
+	}
+
+}

+ 237 - 0
hrt/prefab/ContextShared.hx

@@ -0,0 +1,237 @@
+package hrt.prefab;
+
+typedef ShaderDef = {
+	var shader : hxsl.SharedShader;
+	var inits : Array<{ v : hxsl.Ast.TVar, e : hxsl.Ast.TExpr }>;
+}
+
+typedef ShaderDefCache = Map<String, ShaderDef>;
+
+class ContextShared {
+	public var root2d : h2d.Object;
+	public var root3d : h3d.scene.Object;
+	public var contexts : Map<Prefab,Context>;
+	public var references : Map<Prefab,Array<Context>>;
+	public var currentPath : String;
+	public var editorDisplay : Bool;
+
+	var cache : h3d.prim.ModelCache;
+	var shaderCache : ShaderDefCache;
+	var bakedData : Map<String, haxe.io.Bytes>;
+
+	public function new() {
+		root2d = new h2d.Object();
+		root3d = new h3d.scene.Object();
+		contexts = new Map();
+		references = new Map();
+		cache = new h3d.prim.ModelCache();
+		shaderCache = new ShaderDefCache();
+	}
+
+	public function onError( e : Dynamic ) {
+		throw e;
+	}
+
+	public function elements() {
+		return [for(e in contexts.keys()) e];
+	}
+
+	public function getContexts(p: Prefab) {
+		var ret : Array<Context> = [];
+		var ctx = contexts.get(p);
+		if(ctx != null)
+			ret.push(ctx);
+		var ctxs = references.get(p);
+		if(ctxs != null)
+			return ret.concat(ctxs);
+		return ret;
+	}
+
+	public function loadDir(p : String, ?dir : String ) : Array<hxd.res.Any> {
+		var datPath = new haxe.io.Path(currentPath);
+		datPath.ext = "dat";
+		var path = datPath.toString() + "/" + p;
+		if(dir != null) path += "/" + dir;
+		return try hxd.res.Loader.currentInstance.dir(path) catch( e : hxd.res.NotFound ) null;
+	}
+
+	public function loadPrefabDat(file : String, ext : String, p : String) : hxd.res.Any {
+		var datPath = new haxe.io.Path(currentPath);
+		datPath.ext = "dat";
+		var path = new haxe.io.Path(datPath.toString() + "/" + p + "/" + file);
+		path.ext = ext;
+		return try hxd.res.Loader.currentInstance.load(path.toString()) catch( e : hxd.res.NotFound ) null;
+	}
+
+	public function savePrefabDat(file : String, ext : String, p : String, bytes : haxe.io.Bytes ) {
+		throw "Not implemented";
+	}
+
+	public function loadPrefab( path : String ) : Prefab {
+		throw "Not implemented";
+	}
+
+	public function loadShader( path : String ) : ShaderDef {
+		var r = shaderCache.get(path);
+		if(r != null)
+			return r;
+		var cl = Type.resolveClass(path.split("/").join("."));
+		if(cl == null) return null;
+		var shader = new hxsl.SharedShader(Reflect.field(cl, "SRC"));
+		r = {
+			shader: shader,
+			inits: []
+		};
+		shaderCache.set(path, r);
+		return r;
+	}
+
+	public function loadModel( path : String ) {
+		return cache.loadModel(hxd.res.Loader.currentInstance.load(path).toModel());
+	}
+
+	public function loadAnimation( path : String ) {
+		return @:privateAccess cache.loadAnimation(hxd.res.Loader.currentInstance.load(path).toModel());
+	}
+
+	public function loadTexture( path : String ) {
+		return cache.loadTexture(null, path);
+	}
+
+	public function loadBytes( file : String) : haxe.io.Bytes {
+		return try hxd.res.Loader.currentInstance.load(file).entry.getBytes() catch( e : hxd.res.NotFound ) null;
+	}
+
+	public function loadBakedBytes( file : String ) {
+		if( bakedData == null ) loadBakedData();
+		return bakedData.get(file);
+	}
+
+	public function saveBakedBytes( file : String, bytes : haxe.io.Bytes ) {
+		if( bakedData == null ) loadBakedData();
+		if( bytes == null ) {
+			if( !bakedData.remove(file) )
+				return;
+		} else
+			bakedData.set(file, bytes);
+		var keys = Lambda.array({ iterator : bakedData.keys });
+		if( keys.length == 0 ) {
+			saveBakedFile(null);
+			return;
+		}
+		var bytes = new haxe.io.BytesOutput();
+		bytes.writeString("BAKE");
+		bytes.writeInt32(keys.length);
+		var headerSize = 8;
+		for( name in keys )
+			headerSize += 2 + name.length + 8;
+		for( name in keys ) {
+			bytes.writeUInt16(name.length);
+			bytes.writeString(name);
+			bytes.writeInt32(headerSize);
+			var len = bakedData.get(name).length;
+			bytes.writeInt32(len);
+			headerSize += len + 1;
+		}
+		for( name in keys ) {
+			bytes.write(bakedData.get(name));
+			bytes.writeByte(0xFE); // stop
+		}
+		saveBakedFile(bytes.getBytes());
+	}
+
+	public function saveTexture( file : String, bytes : haxe.io.Bytes , dir : String, ext : String) {
+		throw "Don't know how to save texture";
+	}
+
+	function saveBakedFile( bytes : haxe.io.Bytes ) {
+		throw "Don't know how to save baked file";
+	}
+
+	function loadBakedFile() {
+		var path = new haxe.io.Path(currentPath);
+		path.ext = "bake";
+		return try hxd.res.Loader.currentInstance.load(path.toString()).entry.getBytes() catch( e : hxd.res.NotFound ) null;
+	}
+
+	function loadBakedData() {
+		bakedData = new Map();
+		var data = loadBakedFile();
+		if( data == null )
+			return;
+		if( data.getString(0,4) != "BAKE" )
+			throw "Invalid bake file";
+		var count = data.getInt32(4);
+		var pos = 8;
+		for( i in 0...count ) {
+			var len = data.getUInt16(pos);
+			pos += 2;
+			var name = data.getString(pos, len);
+			pos += len;
+			var bytesPos = data.getInt32(pos);
+			pos += 4;
+			var bytesLen = data.getInt32(pos);
+			pos += 4;
+			bakedData.set(name,data.sub(bytesPos,bytesLen));
+			if( data.get(bytesPos+bytesLen) != 0xFE )
+				throw "Corrupted bake file";
+		}
+	}
+
+	function getChildrenRoots( base : h3d.scene.Object, p : Prefab, out : Array<h3d.scene.Object> ) {
+		for( c in p.children ) {
+			var ctx = contexts.get(c);
+			if( ctx == null ) continue;
+			if( ctx.local3d == base )
+				getChildrenRoots(base, c, out);
+			else
+				out.push(ctx.local3d);
+		}
+		return out;
+	}
+
+	public function getObjects<T:h3d.scene.Object>( p : Prefab, c: Class<T> ) : Array<T> {
+		var ctx = contexts.get(p);
+		if( ctx == null )
+			return [];
+		var root = ctx.local3d;
+		var childObjs = getChildrenRoots(root, p, []);
+		var ret = [];
+		function rec(o : h3d.scene.Object) {
+			var m = Std.instance(o, c);
+			if(m != null) ret.push(m);
+			for( child in o )
+				if( childObjs.indexOf(child) < 0 )
+					rec(child);
+		}
+		rec(root);
+		return ret;
+	}
+
+	public function getMaterials( p : Prefab ) {
+		var ctx = contexts.get(p);
+		if( ctx == null )
+			return [];
+		var root = ctx.local3d;
+		var childObjs = getChildrenRoots(root, p, []);
+		var ret = [];
+		function rec(o : h3d.scene.Object) {
+			if( o.isMesh() ) {
+				var m = o.toMesh();
+				var multi = Std.instance(m, h3d.scene.MultiMaterial);
+				if( multi != null ) {
+					for( m in multi.materials )
+						if( m != null )
+							ret.push(m);
+				} else if( m.material != null )
+					ret.push(m.material);
+			}
+			for( child in o )
+				if( childObjs.indexOf(child) < 0 )
+					rec(child);
+		}
+		rec(root);
+		return ret;
+	}
+
+}

+ 1 - 1
hrt/prefab/Curve.hx

@@ -339,5 +339,5 @@ class Curve extends Prefab {
 			a != null ? VCurve(a) : VConst(1.0));
 	}
 
-	static var _ = hxd.prefab.Library.register("curve", Curve);
+	static var _ = Library.register("curve", Curve);
 }

+ 77 - 0
hrt/prefab/Library.hx

@@ -0,0 +1,77 @@
+package hrt.prefab;
+
+class Library extends Prefab {
+
+	public function new() {
+		super(null);
+		type = "prefab";
+	}
+
+	override function load( obj : Dynamic ) {
+	}
+
+	override function save() {
+		return {};
+	}
+
+	/**
+		Returns the prefab within children that matches the given absolute path
+	**/
+	public function getFromPath( path : String ) : Prefab {
+		var parts = path.split(".");
+		var cur : Prefab = this;
+		for( p in parts ) {
+			var found = false;
+			for( c in cur.children )
+				if( c.name == p ) {
+					found = true;
+					cur = c;
+					break;
+				}
+			if( !found ) return null;
+		}
+		return cur;
+	}
+
+	static var registeredElements = new Map<String,{ cl : Class<Prefab> #if editor, inf : hide.prefab.HideProps #end }>();
+	static var registeredExtensions = new Map<String,String>();
+
+	public static function getRegistered() {
+		return registeredElements;
+	}
+
+	public static function isOfType( prefabKind : String, cl : Class<Prefab> ) {
+		var inf = registeredElements.get(prefabKind);
+		if( inf == null ) return false;
+		var c : Class<Dynamic> = inf.cl;
+		while( c != null ) {
+			if( c == cl ) return true;
+			c = Type.getSuperClass(c);
+		}
+		return false;
+	}
+
+	public static function register( type : String, cl : Class<Prefab>, ?extension : String ) {
+		registeredElements.set(type, { cl : cl #if editor, inf : Type.createEmptyInstance(cl).getHideProps() #end });
+		if( extension != null ) registeredExtensions.set(extension, type);
+		return true;
+	}
+
+	public static function create( extension : String ) {
+		var type = getPrefabType(extension);
+		var p : hrt.prefab.Prefab;
+		if( type == null )
+			p = new Library();
+		else
+			p = Type.createInstance(registeredElements.get(type).cl,[]);
+		return p;
+	}
+
+	public static function getPrefabType(path: String) {
+		var extension = path.split(".").pop().toLowerCase();
+		return registeredExtensions.get(extension);
+	}
+
+	static var _ = Library.register("prefab", Library, "prefab");
+
+}

+ 1 - 1
hrt/prefab/Light.hx

@@ -538,5 +538,5 @@ class Light extends Object3D {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("light", Light);
+	static var _ = Library.register("light", Light);
 }

+ 3 - 4
hrt/prefab/Material.hx

@@ -1,6 +1,5 @@
 package hrt.prefab;
 
-
 class Material extends Prefab {
 
 	public var wrapRepeat = false;
@@ -95,7 +94,7 @@ class Material extends Prefab {
 			return;
 
 		var obj = ctx.local3d;
-		if(parent != null && Type.getClass(parent) == hrt.prefab.Object3D) {
+		if(parent != null && Type.getClass(parent) == Object3D) {
 			for(i in 0...obj.numChildren) {
 				updateObject(ctx, obj.getChildAt(i));
 			}
@@ -155,10 +154,10 @@ class Material extends Prefab {
 	public static function hasOverride(p: Prefab) {
 		if(Lambda.exists(p.children, c -> Std.is(c, Material) && c.enabled))
 			return true;
-		if(Type.getClass(p.parent) == hrt.prefab.Object3D)
+		if(Type.getClass(p.parent) == Object3D)
 			return Lambda.exists(p.parent.children, c -> Std.is(c, Material) && c.enabled);
 		return false;
 	}
 
-	static var _ = hxd.prefab.Library.register("material", Material);
+	static var _ = Library.register("material", Material);
 }

+ 2 - 2
hrt/prefab/Model.hx

@@ -122,12 +122,12 @@ class Model extends Object3D {
 	override function getHideProps() : HideProps {
 		return {
 			icon : "cube", name : "Model", fileSource : ["fbx","hmd"],
-			allowChildren : function(t) return hxd.prefab.Library.isOfType(t,Object3D) || ["material", "shader"].indexOf(t) >= 0,
+			allowChildren : function(t) return Library.isOfType(t,Object3D) || ["material", "shader"].indexOf(t) >= 0,
 			onResourceRenamed : function(f) animation = f(animation),
 		};
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("model", Model);
+	static var _ = Library.register("model", Model);
 
 }

+ 1 - 1
hrt/prefab/Noise.hx

@@ -237,7 +237,7 @@ class Noise extends Prefab {
 
 	#end
 
-	static var _ = hxd.prefab.Library.register("noise", Noise);
+	static var _ = Library.register("noise", Noise);
 
 }
 

+ 1 - 1
hrt/prefab/Object3D.hx

@@ -160,6 +160,6 @@ class Object3D extends Prefab {
 		return type == "object" ? "group" : super.getDefaultName();
 	}
 
-	static var _ = hxd.prefab.Library.register("object", Object3D);
+	static var _ = Library.register("object", Object3D);
 
 }

+ 413 - 0
hrt/prefab/Prefab.hx

@@ -0,0 +1,413 @@
+package hrt.prefab;
+
+/**
+	Prefab is an data-oriented tree container capable of creating instances of Heaps objects.
+**/
+@:keepSub
+class Prefab {
+
+	/**
+		The type of prefab, allows to identify which class it should be loaded with.
+	**/
+	public var type(default, null) : String;
+
+	/**
+		The name of the prefab in the tree view
+	**/
+	public var name(default, set) : String;
+
+	/**
+		The parent of the prefab in the tree view
+	**/
+	public var parent(default, set) : Prefab;
+
+	/**
+		The associated source file (an image, a 3D model, etc.) if the prefab type needs it.
+	**/
+	public var source(default, set) : String;
+
+	/**
+		The list of children prefab in the tree view
+	**/
+	public var children(default, null) : Array<Prefab>;
+
+	/**
+		Tells if the prefab will create an instance when calling make() or be ignored. Also apply to this prefab children.
+	**/
+	public var enabled : Bool = true;
+
+
+	/**
+		A storage for some extra properties
+	**/
+	public var props : Any;
+
+	/**
+		Creates a new prefab with the given parent.
+	**/
+	public function new(?parent) {
+		this.parent = parent;
+		children = [];
+	}
+
+	function set_name(n) {
+		return name = n;
+	}
+
+	function set_source(f) {
+		return source = f;
+	}
+
+	function set_parent(p) {
+		if( parent != null )
+			parent.children.remove(this);
+		parent = p;
+		if( parent != null )
+			parent.children.push(this);
+		return p;
+	}
+
+	#if editor
+
+	/**
+		Allows to customize how the prefab object is edited within Hide
+	**/
+	public function edit( ctx : hide.prefab.EditContext ) {
+	}
+
+	/**
+		Allows to customize how the prefab object is displayed / handled within Hide
+	**/
+	public function getHideProps() : hide.prefab.HideProps {
+		return { icon : "question-circle", name : "Unknown" };
+	}
+
+	/**
+		Allows to customize how the prefab instance changes when selected/unselected within Hide
+	**/
+	public function setSelected( ctx : Context, b : Bool ) {
+		var materials = ctx.shared.getMaterials(this);
+
+		if( !b ) {
+			for( m in materials ) {
+				m.mainPass.stencil = null;
+				m.removePass(m.getPass("highlight"));
+			}
+			return;
+		}
+
+		var shader = new h3d.shader.FixedColor(0xffffff);
+		for( m in materials ) {
+			var p = m.allocPass("highlight");
+			p.culling = None;
+			p.depthWrite = false;
+			p.addShader(shader);
+		}
+	}
+	#end
+
+	/**
+		Iterate over children prefab
+	**/
+	public inline function iterator() : Iterator<Prefab> {
+		return children.iterator();
+	}
+
+	/**
+		Override to implement your custom prefab data loading
+	**/
+	function load( v : Dynamic ) {
+		throw "Not implemented";
+	}
+
+	/**
+		Override to implement your custom prefab data saving
+	**/
+	function save() : {} {
+		throw "Not implemented";
+		return null;
+	}
+
+	/**
+		Creates an instance for this prefab only (and not its children).
+		Use make(ctx) to creates the whole instances tree;
+	**/
+	public function makeInstance( ctx : Context ) : Context {
+		return ctx;
+	}
+
+	/**
+		Allows to customize how an instance gets updated when a property name changes.
+		You can also call updateInstance(ctx) in order to force whole instance synchronization against current prefab data.
+	**/
+	public function updateInstance( ctx : Context, ?propName : String ) {
+	}
+
+	/**
+		Removes the created instance for this prefab only (not is children).
+		If false is returned, the instance could not be removed and the whole context scene needs to be rebuilt
+	**/
+	public function removeInstance( ctx : Context ) : Bool {
+		return false;
+	}
+
+	/**
+		Save the whole prefab data and its children.
+	**/
+	@:final public function saveData() : {} {
+		var obj : Dynamic = save();
+		obj.type = type;
+		if( !enabled )
+			obj.enabled = false;
+		if( name != null )
+			obj.name = name;
+		if( source != null )
+			obj.source = source;
+		if( children.length > 0 )
+			obj.children = [for( s in children ) s.saveData()];
+		if( props != null && obj.props == null )
+			obj.props = props;
+		return obj;
+	}
+
+	/**
+		Load the whole prefab data and creates its children.
+	**/
+	@:final public function loadData( v : Dynamic ) {
+		type = v.type;
+		name = v.name;
+		enabled = v.enabled == null ? true : v.enabled;
+		props = v.props;
+		source = v.source;
+		load(v);
+		if( children.length > 0 )
+			children = [];
+		var children : Array<Dynamic> = v.children;
+		if( children != null )
+			for( v in children )
+				loadPrefab(v, this);
+	}
+
+	/**
+		Updates in-place the whole prefab data and its children.
+	**/
+	public function reload( p : Dynamic ) {
+		name = p.name;
+		enabled = p.enabled == null ? true : p.enabled;
+		props = p.props;
+		source = p.source;
+		load(p);
+		var childData : Array<Dynamic> = p.children;
+		if( childData == null ) {
+			if( this.children.length > 0 ) this.children = [];
+			return;
+		}
+		var curChild = new Map();
+		for( c in children )
+			curChild.set(c.name, c);
+		var newchild = [];
+		for( v in childData ) {
+			var name : String = v.name;
+			var prev = curChild.get(name);
+			if( prev != null && prev.type == v.type ) {
+				curChild.remove(name);
+				prev.reload(v);
+				newchild.push(prev);
+			} else {
+				newchild.push(loadPrefab(v,this));
+			}
+		}
+		children = newchild;
+	}
+
+	/**
+		Creates the correct prefab based on v.type and load its data and children.
+		If one the prefab in the tree is not registered, a hxd.prefab.Unkown is created instead.
+	**/
+	public static function loadPrefab( v : Dynamic, ?parent : Prefab ) {
+		var pcl = @:privateAccess Library.registeredElements.get(v.type);
+		var pcl = pcl == null ? null : pcl.cl;
+		if( pcl == null ) pcl = Unknown;
+		var p = Type.createInstance(pcl, [parent]);
+		p.loadData(v);
+		return p;
+	}
+
+	/**
+		Creates an instance for this prefab and its children.
+	**/
+	public function make( ctx : Context ) : Context {
+		if( !enabled )
+			return ctx;
+		if( ctx == null ) {
+			ctx = new Context();
+			ctx.init();
+		}
+		ctx = makeInstance(ctx);
+		for( c in children )
+			c.make(ctx);
+		return ctx;
+	}
+
+	#if castle
+	/**
+		Returns which CDB model this prefab props represents
+	**/
+	public function getCdbModel( ?p : Prefab ) : cdb.Sheet {
+		if( p == null )
+			p = this;
+		if( parent != null )
+			return parent.getCdbModel(p);
+		return null;
+	}
+	#end
+
+	/**
+		Search the prefab tree for the prefab matching the given name, returns null if not found
+	**/
+	public function getPrefabByName( name : String ) {
+		if( this.name == name )
+			return this;
+		for( c in children ) {
+			var p = c.getPrefabByName(name);
+			if( p != null )
+				return p;
+		}
+		return null;
+	}
+
+	/**
+		Simlar to get() but returns null if not found.
+	**/
+	public function getOpt<T:Prefab>( cl : Class<T>, ?name : String ) : T {
+		if( name == null || this.name == name ) {
+			var cval = to(cl);
+			if( cval != null ) return cval;
+		}
+		for( c in children ) {
+			var p = c.getOpt(cl, name);
+			if( p != null )
+				return p;
+		}
+		return null;
+	}
+
+	/**
+		Search the prefab tree for the prefab matching the given prefab class (and name, if specified).
+		Throw an exception if not found. Uses getOpt() to return null instead.
+	**/
+	public function get<T:Prefab>( cl : Class<T>, ?name : String ) : T {
+		var v = getOpt(cl, name);
+		if( v == null )
+			throw "Missing prefab " + (name == null ? Type.getClassName(cl) : (cl == null ? name : name+"(" + Type.getClassName(cl) + ")"));
+		return v;
+	}
+
+	/**
+		Return all prefabs in the tree matching the given prefab class.
+	**/
+	public function getAll<T:Prefab>( cl : Class<T>, ?arr: Array<T> ) : Array<T> {
+		return findAll(function(p) return p.to(cl));
+	}
+
+	/**
+		Find a single prefab in the tree by calling `f` on each and returning the first not-null value returned, or null if not found.
+	**/
+	public function find<T>( f : Prefab -> Null<T> ) : Null<T> {
+		var v = f(this);
+		if( v != null )
+			return v;
+		for( p in children ) {
+			var v = p.find(f);
+			if( v != null ) return v;
+		}
+		return null;
+	}
+
+	/**
+		Find several prefabs in the tree by calling `f` on each and returning all the not-null values returned.
+	**/
+	public function findAll<T>( f : Prefab -> Null<T>, ?arr : Array<T> ) : Array<T> {
+		if( arr == null ) arr = [];
+		var v = f(this);
+		if( v != null )
+			arr.push(v);
+		for( o in children )
+			o.findAll(f,arr);
+		return arr;
+	}
+
+	/**
+		Returns all prefabs in the tree matching the specified class.
+	**/
+	public function flatten<T:Prefab>( ?cl : Class<T>, ?arr: Array<T> ) : Array<T> {
+		if(arr == null)
+			arr = [];
+		if( cl == null )
+			arr.push(cast this);
+		else {
+			var i = to(cl);
+			if(i != null)
+				arr.push(i);
+		}
+		for(c in children)
+			c.flatten(cl, arr);
+		return arr;
+	}
+
+	/**
+		Returns the first parent in the tree matching the specified class or null if not found.
+	**/
+	public function getParent<T:Prefab>( c : Class<T> ) : Null<T> {
+		var p = parent;
+		while(p != null) {
+			var inst = p.to(c);
+			if(inst != null) return inst;
+			p = p.parent;
+		}
+		return null;
+	}
+
+	/**
+		Converts the prefab to another prefab class.
+		Returns null if not of this type.
+	**/
+	public function to<T:Prefab>( c : Class<T> ) : Null<T> {
+		return Std.instance(this, c);
+	}
+
+	/**
+		Returns the absolute name path for this prefab
+	**/
+	public function getAbsPath() {
+		var p = this;
+		var path = [];
+		while(p.parent != null) {
+			var n = p.name;
+			if( n == null ) n = getDefaultName();
+			path.unshift(n);
+			p = p.parent;
+		}
+		return path.join('.');
+	}
+
+	/**
+		Returns the default name for this prefab
+	**/
+	public function getDefaultName() : String {
+		if(source != null) {
+			var f = new haxe.io.Path(source).file;
+			f = f.split(" ")[0].split("-")[0];
+			return f;
+		}
+		return type.split(".").pop();
+	}
+
+	/**
+		Clone this prefab and all its children
+	**/
+	public function clone() : Prefab {
+		var obj = saveData();
+		return loadPrefab(haxe.Json.parse(haxe.Json.stringify(obj)));
+	}
+}

+ 3 - 3
hrt/prefab/Reference.hx

@@ -27,7 +27,7 @@ class Reference extends Object3D {
 		refpath = o.refpath;
 	}
 
-	public function resolveRef(shared : hxd.prefab.ContextShared) {
+	public function resolveRef(shared : hrt.prefab.ContextShared) {
 		if(ref != null)
 			return ref;
 		if(refpath == null)
@@ -45,7 +45,7 @@ class Reference extends Object3D {
 			return ref;
 		}
 		else {
-			var lib = getParent(hxd.prefab.Library);
+			var lib = getParent(hrt.prefab.Library);
 			if(lib == null)
 				return null;
 			var all = lib.getAll(Prefab);
@@ -143,5 +143,5 @@ class Reference extends Object3D {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("reference", Reference);
+	static var _ = Library.register("reference", Reference);
 }

+ 3 - 3
hrt/prefab/RenderProps.hx

@@ -62,7 +62,7 @@ class RenderProps extends Prefab {
 			fx.dispose();
 		renderer.effects = [];
 		for( s in children ) {
-			var fx = Std.instance(s, hxd.prefab.rfx.RendererFX);
+			var fx = Std.instance(s, hrt.prefab.rfx.RendererFX);
 			if( fx != null )
 				renderer.effects.push(fx);
 		}
@@ -92,10 +92,10 @@ class RenderProps extends Prefab {
 	}
 
 	override function getHideProps() : HideProps {
-		return { icon : "sun-o", name : "RenderProps", allowChildren : function(t) return hxd.prefab.Library.isOfType(t,hxd.prefab.rfx.RendererFX) };
+		return { icon : "sun-o", name : "RenderProps", allowChildren : function(t) return Library.isOfType(t,hrt.prefab.rfx.RendererFX) };
 	}
 
 	#end
 
-	static var _ = hxd.prefab.Library.register("renderProps", RenderProps);
+	static var _ = Library.register("renderProps", RenderProps);
 }

+ 1 - 1
hrt/prefab/Scene.hx

@@ -37,6 +37,6 @@ class Scene extends Prefab {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("scene", Scene);
+	static var _ = Library.register("scene", Scene);
 
 }

+ 1 - 1
hrt/prefab/Settings.hx

@@ -110,6 +110,6 @@ class Settings extends Prefab {
 
 	#end
 
-	static var _ = hxd.prefab.Library.register("settings", Settings);
+	static var _ = Library.register("settings", Settings);
 
 }

+ 2 - 2
hrt/prefab/Shader.hx

@@ -2,7 +2,7 @@ package hrt.prefab;
 
 class Shader extends Prefab {
 
-	public var shaderDef : hxd.prefab.ContextShared.ShaderDef;
+	public var shaderDef : hrt.prefab.ContextShared.ShaderDef;
 
 	public function new(?parent) {
 		super(parent);
@@ -190,5 +190,5 @@ class Shader extends Prefab {
 		return null;
 	}
 
-	static var _ = hxd.prefab.Library.register("shader", Shader);
+	static var _ = Library.register("shader", Shader);
 }

+ 1 - 1
hrt/prefab/Trail.hx

@@ -68,6 +68,6 @@ class Trail extends Object3D {
 
 	#end
 
-	static var _ = hxd.prefab.Library.register("trail", Trail);
+	static var _ = Library.register("trail", Trail);
 
 }

+ 26 - 0
hrt/prefab/Unknown.hx

@@ -0,0 +1,26 @@
+package hrt.prefab;
+
+class Unknown extends Prefab {
+
+	var data : Dynamic;
+
+	public function getPrefabType() {
+		return data.type;
+	}
+
+	override function load(v:Dynamic) {
+		this.data = v;
+	}
+
+	override function save() {
+		return data;
+	}
+
+	#if editor
+	override function edit(ctx:hide.prefab.EditContext) {
+		ctx.properties.add(new hide.Element('<font color="red">Unknown prefab $type</font>'));
+	}
+	#end
+
+
+}

+ 1 - 1
hrt/prefab/fx/AnimEvent.hx

@@ -116,6 +116,6 @@ class AnimEvent extends hrt.prefab.fx.Event {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("animEvent", AnimEvent);
+	static var _ = Library.register("animEvent", AnimEvent);
 
 }

+ 2 - 2
hrt/prefab/fx/Emitter.hx

@@ -304,7 +304,7 @@ class EmitterObject extends h3d.scene.Object {
 
 	var random: hxd.Rand;
 	var randomSeed = 0;
-	var context : hxd.prefab.Context;
+	var context : hrt.prefab.Context;
 	var emitCount = 0;
 	var lastTime = -1.0;
 	var curTime = 0.0;
@@ -1076,6 +1076,6 @@ class Emitter extends Object3D {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("emitter", Emitter);
+	static var _ = Library.register("emitter", Emitter);
 
 }

+ 1 - 1
hrt/prefab/fx/Event.hx

@@ -6,7 +6,7 @@ typedef EventInstance = {
 	setTime: Float->Void
 };
 
-class Event extends hxd.prefab.Prefab {
+class Event extends hrt.prefab.Prefab {
 	public var time: Float = 0.0;
 
 	override function save() : {} {

+ 3 - 3
hrt/prefab/fx/FX.hx

@@ -1,6 +1,6 @@
 package hrt.prefab.fx;
 import hrt.prefab.Curve;
-import hxd.prefab.Prefab as PrefabElement;
+import hrt.prefab.Prefab as PrefabElement;
 
 typedef ShaderParam = {
 	def: hxsl.Ast.TVar,
@@ -216,7 +216,7 @@ class FXAnimation extends h3d.scene.Object {
 	}
 }
 
-class FX extends hxd.prefab.Library {
+class FX extends hrt.prefab.Library {
 
 	public var duration : Float;
 	public var loopAnims : Bool;
@@ -490,5 +490,5 @@ class FX extends hxd.prefab.Library {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("fx", FX, "fx");
+	static var _ = Library.register("fx", FX, "fx");
 }

+ 2 - 2
hrt/prefab/fx/LookAt.hx

@@ -111,7 +111,7 @@ class LookAt extends Object3D {
 		return obj;
 	}
 
-	override function updateInstance(ctx:hxd.prefab.Context, ?propName:String) {
+	override function updateInstance(ctx:hrt.prefab.Context, ?propName:String) {
 		super.updateInstance(ctx, propName);
 		var targetObj = null;
 		if(target != "camera")
@@ -162,5 +162,5 @@ class LookAt extends Object3D {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("lookAt", LookAt);
+	static var _ = Library.register("lookAt", LookAt);
 }

+ 0 - 2
hrt/prefab/import.hx

@@ -1,7 +1,5 @@
 package hrt.prefab;
 
-import hxd.prefab.Prefab;
-import hxd.prefab.Context;
 #if editor
 import hide.prefab.EditContext;
 import hide.prefab.HideProps;

+ 1 - 1
hrt/prefab/l3d/AdvancedDecal.hx

@@ -223,6 +223,6 @@ class AdvancedDecal extends Object3D {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("advancedDecal", AdvancedDecal);
+	static var _ = Library.register("advancedDecal", AdvancedDecal);
 
 }

+ 2 - 2
hrt/prefab/l3d/Camera.hx

@@ -1,6 +1,6 @@
 package hrt.prefab.l3d;
-import hxd.prefab.Context;
-import hxd.prefab.Library;
+import hrt.prefab.Context;
+import hrt.prefab.Library;
 
 class Camera extends Object3D {
 

+ 1 - 1
hrt/prefab/l3d/Decal.hx

@@ -106,6 +106,6 @@ class Decal extends Object3D {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("decal", Decal);
+	static var _ = Library.register("decal", Decal);
 
 }

+ 3 - 3
hrt/prefab/l3d/Instance.hx

@@ -19,7 +19,7 @@ class Instance extends Object3D {
 		var modelPath = findModelPath(kind.sheet, kind.idx.obj);
 		if(modelPath != null) {
 			try {
-				if(hxd.prefab.Library.getPrefabType(modelPath) != null) {
+				if(hrt.prefab.Library.getPrefabType(modelPath) != null) {
 					var ref = ctx.shared.loadPrefab(modelPath);
 					var ctx = ctx.clone(this);
 					ctx.isRef = true;
@@ -96,7 +96,7 @@ class Instance extends Object3D {
 		function filter(f: String) {
 			if(f != null) {
 				var lower = f.toLowerCase();
-				if(StringTools.endsWith(lower, ".fbx") || hxd.prefab.Library.getPrefabType(lower) != null)
+				if(StringTools.endsWith(lower, ".fbx") || hrt.prefab.Library.getPrefabType(lower) != null)
 					return f;
 			}
 			return null;
@@ -163,5 +163,5 @@ class Instance extends Object3D {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("instance", Instance);
+	static var _ = Library.register("instance", Instance);
 }

+ 6 - 9
hrt/prefab/l3d/Level3D.hx

@@ -1,6 +1,6 @@
 package hrt.prefab.l3d;
 
-class Level3D extends hxd.prefab.Library {
+class Level3D extends hrt.prefab.Library {
 
 	public var width : Int = 100;
 	public var height : Int = 100;
@@ -23,15 +23,12 @@ class Level3D extends hxd.prefab.Library {
 		height = obj.height == null ? 100 : obj.height;
 	}
 
-	override function getCdbModel(?p:hxd.prefab.Prefab):cdb.Sheet {
-		#if (editor && castle)
+	#if editor
+
+	override function getCdbModel(?p:hrt.prefab.Prefab) : cdb.Sheet {
 		return hide.view.l3d.Level3D.getCdbModel(p);
-		#end
-		return null;
 	}
 
-	#if editor
-
 	override function edit( ctx : EditContext ) {
 		var props = new hide.Element('
 			<div class="group" name="Level">
@@ -47,10 +44,10 @@ class Level3D extends hxd.prefab.Library {
 	}
 
 	override function getHideProps() : HideProps {
-		return { icon : "cube", name : "Level3D", allowChildren : function(t) return hxd.prefab.Library.isOfType(t,Object3D), allowParent: _ -> false};
+		return { icon : "cube", name : "Level3D", allowChildren : function(t) return Library.isOfType(t,Object3D), allowParent: _ -> false};
 	}
 
 	#end
 
-	static var _ = hxd.prefab.Library.register("level3d", Level3D, "l3d");
+	static var _ = Library.register("level3d", Level3D, "l3d");
 }

+ 1 - 1
hrt/prefab/l3d/MeshGenerator.hx

@@ -463,5 +463,5 @@ class MeshGenerator extends Object3D {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("meshGenerator", MeshGenerator);
+	static var _ = Library.register("meshGenerator", MeshGenerator);
 }

+ 1 - 1
hrt/prefab/l3d/Polygon.hx

@@ -353,5 +353,5 @@ class Polygon extends Object3D {
 
 	#end
 
-	static var _ = hxd.prefab.Library.register("polygon", Polygon);
+	static var _ = Library.register("polygon", Polygon);
 }

+ 1 - 1
hrt/prefab/l3d/VolumetricLightmap.hx

@@ -311,5 +311,5 @@ class VolumetricLightmap extends Object3D {
 
 	#end
 
-	static var _ = hxd.prefab.Library.register("volumetricLightmap", VolumetricLightmap);
+	static var _ = Library.register("volumetricLightmap", VolumetricLightmap);
 }

+ 71 - 0
hrt/prefab/rfx/Bloom.hx

@@ -0,0 +1,71 @@
+package hrt.prefab.rfx;
+
+typedef BloomProps = {
+	var size : Float;
+	var threshold : Float;
+	var intensity : Float;
+	var blur : Float;
+	var saturation : Float;
+	var blurQuality : Float;
+	var blurLinear : Float;
+}
+
+class Bloom extends RendererFX {
+
+	var bloomPass = new h3d.pass.ScreenFx(new h3d.shader.pbr.Bloom());
+	var bloomBlur = new h3d.pass.Blur();
+
+	public function new(?parent) {
+		super(parent);
+		props = ({
+			size : 0.5,
+			blur : 3,
+			intensity : 1.,
+			threshold : 0.5,
+			saturation: 0,
+			blurQuality: 1.0,
+			blurLinear : 0.0,
+		} : BloomProps);
+	}
+
+	override function apply(r:h3d.scene.Renderer, step:h3d.impl.RendererFX.Step) {
+		if( step == BeforeTonemapping ) {
+			var pb : BloomProps = props;
+			var bloom = r.allocTarget("bloom", false, pb.size, RGBA16F);
+			var ctx = r.ctx;
+			ctx.engine.pushTarget(bloom);
+			bloomPass.shader.hdr = ctx.getGlobal("hdr");
+			bloomPass.shader.threshold = pb.threshold;
+			bloomPass.shader.intensity = pb.intensity;
+			bloomPass.shader.colorMatrix.identity();
+			bloomPass.shader.colorMatrix.colorSaturate(pb.saturation);
+			bloomPass.render();
+			ctx.engine.popTarget();
+
+			bloomBlur.radius = pb.blur;
+			bloomBlur.quality = pb.blurQuality;
+			bloomBlur.linear = pb.blurLinear;
+			bloomBlur.apply(ctx, bloom);
+			ctx.setGlobal("bloom",bloom);
+		}
+	}
+
+	#if editor
+	override function edit( ctx : hide.prefab.EditContext ) {
+		ctx.properties.add(new hide.Element('
+			<dl>
+			<dt>Intensity</dt><dd><input type="range" min="0" max="2" field="intensity"/></dd>
+			<dt>Threshold</dt><dd><input type="range" min="0" max="1" field="threshold"/></dd>
+			<dt>Size</dt><dd><input type="range" min="0" max="1" field="size"/></dd>
+			<dt>Blur</dt><dd><input type="range" min="0" max="20" field="blur"/></dd>
+			<dt>Saturation</dt><dd><input type="range" min="-1" max="1" field="saturation"/></dd>
+			<dt>Blur Quality</dt><dd><input type="range" min="0" max="1" field="blurQuality"/></dd>
+			<dt>Blur Linear</dt><dd><input type="range" min="0" max="1" field="blurLinear"/></dd>
+			</dl>
+		'),props);
+	}
+	#end
+
+	static var _ = Library.register("rfx.bloom", Bloom);
+
+}

+ 82 - 0
hrt/prefab/rfx/DistanceFog.hx

@@ -0,0 +1,82 @@
+package hrt.prefab.rfx;
+
+typedef DistanceFogProps = {
+ 	var startDistance : Float;
+	var endDistance : Float;
+	var startOpacity : Float;
+	var endOpacity : Float;
+
+	var startColor : Int;
+	var endColor : Int;
+	var startColorDistance : Float;
+	var endColorDistance : Float;
+}
+
+class DistanceFog extends RendererFX {
+
+	var fogPass = new h3d.pass.ScreenFx(new h3d.shader.DistanceFog());
+
+	public function new(?parent) {
+		super(parent);
+		props = ({
+			startDistance : 0,
+			endDistance : 100,
+			startOpacity : 0,
+			endOpacity : 1,
+		 	startColor : 0xffffff,
+	    	endColor : 0xffffff,
+			startColorDistance : 0,
+			endColorDistance : 100,
+		} : DistanceFogProps);
+
+		fogPass.pass.setBlendMode(Alpha);
+	}
+
+	override function apply(r:h3d.scene.Renderer, step:h3d.impl.RendererFX.Step) {
+		if( step == BeforeTonemapping ) {
+			var p : DistanceFogProps = props;
+			var ctx = r.ctx;
+			var depth : hxsl.ChannelTexture = ctx.getGlobal("depthMap");
+
+			fogPass.shader.startDistance = p.startDistance;
+			fogPass.shader.endDistance = p.endDistance;
+			fogPass.shader.startOpacity = p.startOpacity;
+			fogPass.shader.endOpacity = p.endOpacity;
+			fogPass.shader.startColorDistance = p.startColorDistance;
+			fogPass.shader.endColorDistance = p.endColorDistance;
+			fogPass.shader.startColor = h3d.Vector.fromColor(p.startColor);
+			fogPass.shader.endColor = h3d.Vector.fromColor(p.endColor);
+			fogPass.shader.depthTextureChannel = depth.channel;
+			fogPass.shader.depthTexture = depth.texture;
+
+			fogPass.shader.cameraPos = ctx.camera.pos;
+			fogPass.shader.cameraInverseViewProj.load(ctx.camera.getInverseViewProj());
+
+			fogPass.render();
+		}
+	}
+
+	#if editor
+	override function edit( ctx : hide.prefab.EditContext ) {
+		ctx.properties.add(new hide.Element('
+			<dl>
+				<div class="group" name="Opacity">
+					<dt>Start Distance</dt><dd><input type="range" min="0" max="100" field="startDistance"/></dd>
+					<dt>End Distance</dt><dd><input type="range" min="0" max="100" field="endDistance"/></dd>
+					<dt>Start Opacity</dt><dd><input type="range" min="0" max="1" field="startOpacity"/></dd>
+					<dt>End Opacity</dt><dd><input type="range" min="0" max="1" field="endOpacity"/></dd>
+				</div>
+				<div class="group" name="Color">
+					<dt>Start Distance</dt><dd><input type="range" min="0" max="100" field="startColorDistance"/></dd>
+					<dt>End Distance</dt><dd><input type="range" min="0" max="100" field="endColorDistance"/></dd>
+					<dt>Start Color</dt><dd><input type="color" field="startColor"/></dd>
+					<dt>End Color</dt><dd><input type="color" field="endColor"/></dd>
+				</div>
+			</dl>
+		'),props);
+	}
+	#end
+
+	static var _ = Library.register("rfx.distanceFog", DistanceFog);
+
+}

+ 24 - 0
hrt/prefab/rfx/RendererFX.hx

@@ -0,0 +1,24 @@
+package hrt.prefab.rfx;
+
+class RendererFX extends Prefab implements h3d.impl.RendererFX {
+
+	public function apply( r : h3d.scene.Renderer, step : h3d.impl.RendererFX.Step ) {
+	}
+
+	override function save() {
+		return {};
+	}
+
+	override function load(v:Dynamic) {
+	}
+
+	public function dispose() {
+	}
+
+	#if editor
+	override function getHideProps() : hide.prefab.HideProps {
+		return { name : Type.getClassName(Type.getClass(this)).split(".").pop(), icon : "plus-circle" };
+	}
+	#end
+
+}

+ 86 - 0
hrt/prefab/rfx/Sao.hx

@@ -0,0 +1,86 @@
+package hrt.prefab.rfx;
+
+typedef SaoProps = {
+	var size : Float;
+	var blur : Float;
+	var samples : Int;
+	var radius : Float;
+	var intensity : Float;
+	var bias : Float;
+	var microIntensity : Float;
+	var useWorldUV : Bool;
+}
+
+class Sao extends RendererFX {
+
+	var sao : h3d.pass.ScalableAO;
+	var saoBlur = new h3d.pass.Blur();
+	var saoCopy = new h3d.pass.Copy();
+
+	public function new(?parent) {
+		super(parent);
+		props = ({
+			size : 1,
+			blur : 5,
+			samples : 30,
+			radius : 1,
+			intensity : 1,
+			bias : 0.1,
+			microIntensity : 1.0,
+			useWorldUV : false,
+		} : SaoProps);
+	}
+
+	override function apply( r : h3d.scene.Renderer, step : h3d.impl.RendererFX.Step ) {
+		if( step == BeforeLighting ) {
+			if( sao == null ) sao = new h3d.pass.ScalableAO();
+			var props : SaoProps = props;
+			var ctx = r.ctx;
+			var saoTex = r.allocTarget("sao",false, props.size);
+			var microOcclusion = r.allocTarget("sao",false, props.size);
+			var normal : hxsl.ChannelTexture = ctx.getGlobal("normalMap");
+			var depth : hxsl.ChannelTexture = ctx.getGlobal("depthMap");
+			var occlu : hxsl.ChannelTexture = ctx.getGlobal("occlusionMap");
+			ctx.engine.pushTarget(saoTex);
+			sao.shader.numSamples = props.samples;
+			sao.shader.sampleRadius	= props.radius;
+			sao.shader.intensity = props.intensity;
+			sao.shader.bias = props.bias * props.bias;
+			sao.shader.depthTextureChannel = depth.channel;
+			sao.shader.normalTextureChannel = normal.channel;
+			sao.shader.useWorldUV = props.useWorldUV;
+			sao.shader.microOcclusion = occlu.texture;
+			sao.shader.microOcclusionChannel = occlu.channel;
+			sao.shader.microOcclusionIntensity = props.microIntensity;
+			sao.apply(depth.texture,normal.texture,ctx.camera);
+			ctx.engine.popTarget();
+
+			saoBlur.radius = props.blur;
+			saoBlur.quality = 0.5;
+			saoBlur.apply(ctx, saoTex);
+
+			saoCopy.pass.setColorChannel(occlu.channel);
+			saoCopy.apply(saoTex, occlu.texture);
+		}
+	}
+
+	#if editor
+	override function edit( ctx : hide.prefab.EditContext ) {
+		ctx.properties.add(new hide.Element('
+			<dl>
+			<dt>Intensity</dt><dd><input type="range" min="0" max="10" field="intensity"/></dd>
+			<dt>Radius</dt><dd><input type="range" min="0" max="10" field="radius"/></dd>
+			<dt>Bias</dt><dd><input type="range" min="0" max="0.5" field="bias"/></dd>
+			<dt>Size</dt><dd><input type="range" min="0" max="1" field="size"/></dd>
+			<dt>Blur</dt><dd><input type="range" min="0" max="20" field="blur"/></dd>
+			<dt>Samples</dt><dd><input type="range" min="3" max="256" field="samples" step="1"/></dd>
+			<dt>Micro Intensity</dt><dd><input type="range" min="0" max="1" field="microIntensity"/></dd>
+			<dt>Use World UV</dt><dd><input type="checkbox" field="useWorldUV"/></dd>
+			</dl>
+		'),props);
+	}
+	#end
+
+	static var _ = Library.register("rfx.sao", Sao);
+
+}

+ 1 - 1
hrt/prefab/terrain/Terrain.hx

@@ -471,5 +471,5 @@ class Terrain extends Object3D {
 	}
 	#end
 
-	static var _ = hxd.prefab.Library.register("terrain", Terrain);
+	static var _ = Library.register("terrain", Terrain);
 }