浏览代码

Prefab works with SceneEditor. No toolbar yet

trethaller 7 年之前
父节点
当前提交
d9d5bc1a55
共有 3 个文件被更改,包括 110 次插入293 次删除
  1. 40 25
      hide/comp/SceneEditor.hx
  2. 68 263
      hide/view/Prefab.hx
  3. 2 5
      hide/view/l3d/Level3D.hx

+ 40 - 25
hide/comp/SceneEditor.hx

@@ -21,13 +21,26 @@ class SceneEditorContext extends hide.prefab.EditContext {
 		rootElements = [];
 		cleanups = [];
 		for(elt in elements) {
+			var obj3d = elt.to(Object3D);
+			if(obj3d == null) continue;
 			if(!SceneEditor.hasParent(elt, elements)) {
 				rootElements.push(elt);
-				rootObjects.push(getContext(elt).local3d);
+				var obj = getContext(elt).local3d;
+				if(obj != null) 
+					rootObjects.push(obj);
 			}
 		}
 	}
 
+	public function objects3D() {
+		var ret = [];
+		for(e in elements) {
+			var obj = e.to(Object3D);
+			if(obj != null) ret.push(obj);
+		}
+		return ret;
+	}
+
 	override function rebuild() {
 		properties.clear();
 		cleanup();
@@ -76,7 +89,7 @@ class SceneEditor {
 		var propsEl = new Element('<div class="props"></div>');
 		properties = new hide.comp.PropsEditor(propsEl, undo);
 
-		var treeEl = new Element('<div class="tree small"></div>');
+		var treeEl = new Element('<div class="tree"></div>');
 		tree = new hide.comp.IconTree(treeEl);
 		tree.async = false;
 
@@ -320,7 +333,7 @@ class SceneEditor {
 				m;
 			}];
 
-			var objects3d = [for(e in curEdit.elements) e.to(Object3D)];
+			var objects3d = curEdit.objects3D();
 			var prevState = [for(o in objects3d) o.save()];
 			var snapGround = mode == MoveXY;
 			gizmo.onMove = function(translate: h3d.Vector, rot: h3d.Quat, scale: h3d.Vector) {
@@ -774,29 +787,31 @@ class SceneEditor {
 			to.children.insert(index, e);
 
 			var obj3d = e.to(Object3D);
-			var obj = getObject(e);
 			var toObj = getObject(to);
-			var mat = worldMat(obj);
-			var parentMat = worldMat(toObj);
-			parentMat.invert();
-			mat.multiply(mat, parentMat);
-			var prevState = obj3d.save();
-			obj3d.setTransform(mat);
-			var newState = obj3d.save();
-
-			undoes.push(function(undo) {
-				if( undo ) {
-					e.parent = prev;
-					prev.children.remove(e);
-					prev.children.insert(prevIndex, e);
-					obj3d.load(prevState);
-				} else {
-					e.parent = to;
-					to.children.remove(e);
-					to.children.insert(index, e);
-					obj3d.load(newState);
-				};
-			});
+			var obj = getObject(e);
+			if(obj3d != null && toObj != null && obj != null) {
+				var mat = worldMat(obj);
+				var parentMat = worldMat(toObj);
+				parentMat.invert();
+				mat.multiply(mat, parentMat);
+				var prevState = obj3d.save();
+				obj3d.setTransform(mat);
+				var newState = obj3d.save();
+
+				undoes.push(function(undo) {
+					if( undo ) {
+						e.parent = prev;
+						prev.children.remove(e);
+						prev.children.insert(prevIndex, e);
+						obj3d.load(prevState);
+					} else {
+						e.parent = to;
+						to.children.remove(e);
+						to.children.insert(index, e);
+						obj3d.load(newState);
+					};
+				});
+			}
 		}
 		return function(undo) {
 			for(f in undoes) {

+ 68 - 263
hide/view/Prefab.hx

@@ -2,50 +2,70 @@ package hide.view;
 
 import hide.prefab.Prefab in PrefabElement;
 
-class EditContext extends hide.prefab.EditContext {
-
-	var view : FileView;
-	public var elt : PrefabElement;
-
-	public function new(ctx, elt, view) {
-		super(ctx);
-		this.elt = elt;
-		this.view = view;
+@:access(hide.view.Prefab)
+class PrefabSceneEditor extends hide.comp.SceneEditor {
+	var parent : Prefab;
+	public function new(view, context, data) {
+		super(view, context, data);
+		parent = cast view;
 	}
 
-	override function rebuild() {
-		properties.clear();
-		cleanup();
-		elt.edit(this);
+	override function update(dt) {
+		super.update(dt);
+		parent.onUpdate(dt);
 	}
 
-	public function cleanup() {
-		for( c in cleanups.copy() )
-			c();
-		cleanups = [];
-	}
+	override function getNewContextMenu() {
+		var current = tree.getCurrentOver();
+		var registered = new Array<hide.comp.ContextMenu.ContextMenuItem>();
+		var allRegs = @:privateAccess hide.prefab.Library.registeredElements;
+		for( ptype in allRegs.keys() ) {
+			if( ptype == "prefab" ) continue;
+			var pcl = allRegs.get(ptype);
+			var props = Type.createEmptyInstance(pcl).getHideProps();
+			registered.push({
+				label : props.name,
+				click : function() {
+
+					function make() {
+						var p = Type.createInstance(pcl, [current == null ? sceneData : current]);
+						@:privateAccess p.type = ptype;
+						autoName(p);
+						return p;
+					}
 
-	override function onChange(p:hide.prefab.Prefab, propName:String) {
-		view.modified = true;
+					if( props.fileSource != null )
+						ide.chooseFile(props.fileSource, function(path) {
+							if( path == null ) return;
+							var p = make();
+							p.source = path;
+							addObject(p);
+						});
+					else
+						addObject(make());
+				}
+			});
+		}
+		return registered;
 	}
-
 }
 
 class Prefab extends FileView {
 
+	var sceneEditor : PrefabSceneEditor;
 	var data : hide.prefab.Library;
 	var context : hide.prefab.Context;
 	var tabs : hide.comp.Tabs;
 
 	var tools : hide.comp.Toolbar;
-	var scene : hide.comp.Scene;
-	var control : h3d.scene.CameraController;
-	var properties : hide.comp.PropsEditor;
 	var light : h3d.scene.DirLight;
 	var lightDirection = new h3d.Vector( 1, 2, -4 );
-	var tree : hide.comp.IconTree<PrefabElement>;
 
-	var curEdit : EditContext;
+
+	var scene(get, null):  hide.comp.Scene;
+	function get_scene() return sceneEditor.scene;
+	var properties(get, null):  hide.comp.PropsEditor;
+	function get_properties() return sceneEditor.properties;
 
 	// autoSync
 	var autoSync : Bool;
@@ -75,6 +95,18 @@ class Prefab extends FileView {
 	}
 
 	override function onDisplay() {
+		saveDisplayKey = "Prefab:" + getPath().split("\\").join("/").substr(0,-1);
+		data = new hide.prefab.Library();
+		var content = sys.io.File.getContent(getPath());
+		data.load(haxe.Json.parse(content));
+		currentSign = haxe.crypto.Md5.encode(content);
+
+		context = new hide.prefab.Context();
+		context.onError = function(e) {
+			ide.error(e);
+		};
+		context.init();
+
 		root.html('
 			<div class="flex vertical">
 				<div class="toolbar"></div>
@@ -84,11 +116,9 @@ class Prefab extends FileView {
 					<div class="tabs">
 						<div class="tab" name="Scene" icon="sitemap">
 							<div class="hide-block">
-								<div class="hide-list">
-									<div class="tree"></div>
+								<div class="hide-list hide-scene-tree">
 								</div>
 							</div>
-							<div class="props"></div>
 						</div>
 					</div>
 				</div>
@@ -96,114 +126,26 @@ class Prefab extends FileView {
 		');
 		tools = new hide.comp.Toolbar(root.find(".toolbar"));
 		tabs = new hide.comp.Tabs(root.find(".tabs"));
-		properties = new hide.comp.PropsEditor(root.find(".props"), undo);
-		scene = new hide.comp.Scene(root.find(".scene"));
-		scene.onReady = init;
-		tree = new hide.comp.IconTree(root.find(".tree"));
+		sceneEditor = new PrefabSceneEditor(this, context, data);
+		root.find(".hide-scene-tree").first().append(sceneEditor.tree.root);
+		root.find(".tab").first().append(sceneEditor.properties.root);
+		root.find(".scene").first().append(sceneEditor.scene.root);
 		currentVersion = undo.currentID;
 	}
 
-	function refresh( ?callb ) {
-		var sh = context.shared;
-		sh.root2d.remove();
-		sh.root3d.remove();
-		for( f in sh.cleanups )
-			f();
-		sh.root2d = new h2d.Sprite();
-		sh.root3d = new h3d.scene.Object();
-		sh.cleanups = [];
-		context.init();
-		data.makeInstance(context);
-		scene.s2d.addChild(sh.root2d);
-		scene.s3d.addChild(sh.root3d);
-		scene.init(props);
-		tree.refresh(callb);
-	}
-
-	function allocName( prefix : String ) {
-		var id = 0;
-		while( data.getPrefabByName(prefix + id) != null )
-			id++;
-		return prefix + id;
-	}
-
-	function selectObject( elt : PrefabElement ) {
-		if( curEdit != null )
-			curEdit.cleanup();
-		var edit = new EditContext(context, elt, this);
-		edit.prefabPath = state.path;
-		edit.properties = properties;
-		edit.scene = scene;
-		edit.cleanups = [];
-		edit.rebuild();
-		curEdit = edit;
-	}
-
-	function resetCamera() {
-		var bounds = context.shared.root2d.getBounds();
-		context.shared.root2d.x = -Std.int(bounds.xMin + bounds.width * 0.5);
-		context.shared.root2d.y = -Std.int(bounds.yMin + bounds.height * 0.5);
-		scene.resetCamera(context.shared.root3d, 1.5);
-		control.loadFromCamera();
-	}
-
-	function addObject( e : PrefabElement ) {
-		var roots = e.parent.children;
-		undo.change(Custom(function(undo) {
-			if( undo )
-				roots.remove(e);
-			else
-				roots.push(e);
-			refresh();
-		}));
-		refresh(function() {
-			tree.setSelection([e]);
-			selectObject(e);
-		});
-		if( e.parent == data && data.children.length == 1 )
-			resetCamera();
-	}
-
-	function init() {
-		data = new hide.prefab.Library();
-		var content = sys.io.File.getContent(getPath());
-		data.load(haxe.Json.parse(content));
-		currentSign = haxe.crypto.Md5.encode(content);
-
-		context = new hide.prefab.Context();
-		context.onError = function(e) {
-			ide.error(e);
-		};
-		context.init();
-		scene.s2d.addChild(context.shared.root2d);
-		scene.s3d.addChild(context.shared.root3d);
-
-		data.makeInstance(context);
-
-		light = scene.s3d.find(function(o) return Std.instance(o, h3d.scene.DirLight));
+	public function onSceneReady() {
+		light = sceneEditor.scene.s3d.find(function(o) return Std.instance(o, h3d.scene.DirLight));
 		if( light == null ) {
 			light = new h3d.scene.DirLight(new h3d.Vector(), scene.s3d);
 			light.enableSpecular = true;
 		} else
 			light = null;
 
-		control = new h3d.scene.CameraController(scene.s3d);
 
 		this.saveDisplayKey = "Scene:" + state.path;
 
-		resetCamera();
-		var cam = getDisplayState("Camera");
-		if( cam != null ) {
-			scene.s3d.camera.pos.set(cam.x, cam.y, cam.z);
-			scene.s3d.camera.target.set(cam.tx, cam.ty, cam.tz);
-		}
-		control.loadFromCamera();
-
-		scene.onUpdate = update;
-		scene.init(props);
-		tools.saveDisplayKey = "SceneTools";
-
-		tools.addButton("video-camera", "Reset Camera", resetCamera);
+		tools.saveDisplayKey = "Prefab/tools";
+		tools.addButton("video-camera", "Perspective camera", () -> sceneEditor.resetCamera(false));
 		tools.addToggle("sun-o", "Enable Lights/Shadows", function(v) {
 			if( !v ) {
 				for( m in context.shared.root3d.getMaterials() ) {
@@ -227,146 +169,10 @@ class Prefab extends FileView {
 		tools.addToggle("refresh", "Auto synchronize", function(b) {
 			autoSync = b;
 		});
-
-		// BUILD scene tree
-
-		function makeItem(o:PrefabElement) : hide.comp.IconTree.IconTreeItem<PrefabElement> {
-			var p = o.getHideProps();
-			return {
-				value : o,
-				text : o.name,
-				icon : "fa fa-"+p.icon,
-				children : o.children.length > 0,
-				state : { opened : true },
-			};
-		}
-		tree.get = function(o:PrefabElement) {
-			var objs = o == null ? data.children : Lambda.array(o);
-			var out = [for( o in objs ) makeItem(o)];
-			return out;
-		};
-		tree.root.parent().contextmenu(function(e) {
-			e.preventDefault();
-			var current = tree.getCurrentOver();
-			tree.setSelection(current == null ? [] : [current]);
-
-			var registered = new Array<hide.comp.ContextMenu.ContextMenuItem>();
-			var allRegs = @:privateAccess hide.prefab.Library.registeredElements;
-			for( ptype in allRegs.keys() ) {
-				if( ptype == "prefab" ) continue;
-				var pcl = allRegs.get(ptype);
-				var props = Type.createEmptyInstance(pcl).getHideProps();
-				registered.push({
-					label : props.name,
-					click : function() {
-
-						function make() {
-							var p = Type.createInstance(pcl, [current == null ? data : current]);
-							@:privateAccess p.type = ptype;
-							p.name = allocName(ptype);
-							return p;
-						}
-
-						if( props.fileSource != null )
-							ide.chooseFile(props.fileSource, function(path) {
-								if( path == null ) return;
-								var p = make();
-								p.source = path;
-								addObject(p);
-							});
-						else
-							addObject(make());
-					}
-				});
-			}
-
-
-			new hide.comp.ContextMenu([
-				{ label : "New...", menu : registered },
-				{ label : "Rename", enabled : current != null, click : function() tree.editNode(current) },
-				{ label : "Delete", enabled : current != null, click : function() {
-					function deleteRec(roots:Array<PrefabElement>) {
-						for( o in roots ) {
-							if( o == current ) {
-								properties.clear();
-								var index = roots.indexOf(o);
-								var contexts = context.shared.contexts;
-								var ctx = contexts.get(o);
-								contexts.remove(o);
-								roots.remove(o);
-								undo.change(Custom(function(undo) {
-									if( undo ) {
-										roots.insert(index, o);
-										contexts.set(o, ctx);
-									}
-									else {
-										roots.remove(o);
-										contexts.remove(o);
-									}
-									refresh();
-								}));
-								refresh();
-								return;
-							}
-							@:privateAccess deleteRec(o.children);
-						}
-					}
-					deleteRec(data.children);
-				} },
-			]);
-		});
-		tree.allowRename = true;
-		tree.init();
-		tree.onClick = selectObject;
-		tree.onRename = function(e, name) {
-			var oldName = e.name;
-			e.name = name;
-			undo.change(Field(e, "name", oldName), function() tree.refresh());
-			return true;
-		};
-		tree.onAllowMove = function(_, _) {
-			return true;
-		};
-		tree.onMove = function(e, to, index) {
-			if( to == null ) to = data;
-			var prev = e.parent;
-			var prevIndex = prev.children.indexOf(e);
-			e.parent = to;
-			to.children.remove(e);
-			to.children.insert(index, e);
-			undo.change(Custom(function(undo) {
-				if( undo ) {
-					e.parent = prev;
-					prev.children.remove(e);
-					prev.children.insert(prevIndex, e);
-				} else {
-					e.parent = to;
-					to.children.remove(e);
-					to.children.insert(index, e);
-				}
-				refresh();
-			}));
-			refresh();
-			return true;
-		};
-
-		scene.onResize = function() {
-			scene.s2d.x = scene.s2d.width >> 1;
-			scene.s2d.y = scene.s2d.height >> 1;
-		};
-		scene.onResize();
-
-		if( curEdit != null ) {
-			curEdit.cleanup();
-			var e = curEdit.elt.name;
-			var elt = data.getPrefabByName(e);
-			if( elt != null ) selectObject(elt);
-		}
 	}
 
-	function update(dt:Float) {
+	function onUpdate(dt:Float) {
 		var cam = scene.s3d.camera;
-		saveDisplayState("Camera", { x : cam.pos.x, y : cam.pos.y, z : cam.pos.z, tx : cam.target.x, ty : cam.target.y, tz : cam.target.z });
 		if( light != null ) {
 			var angle = Math.atan2(cam.target.y - cam.pos.y, cam.target.x - cam.pos.x);
 			light.direction.set(
@@ -383,5 +189,4 @@ class Prefab extends FileView {
 	}
 
 	static var _ = FileTree.registerExtension(Prefab,["prefab"],{ icon : "sitemap", createNew : "Prefab" });
-
 }

+ 2 - 5
hide/view/l3d/Level3D.hx

@@ -64,10 +64,6 @@ class Level3DSceneEditor extends hide.comp.SceneEditor {
 	}
 	override function getNewContextMenu() {
 		var current = tree.getCurrentOver();
-		if(current != null && (curEdit == null || curEdit.elements.indexOf(current) < 0)) {
-			selectObjects([current]);
-		}
-
 		var newItems = new Array<hide.comp.ContextMenu.ContextMenuItem>();
 		var allRegs = @:privateAccess hide.prefab.Library.registeredElements;
 		var allowed = ["model", "object", "layer", "box", "polygon"];
@@ -185,10 +181,10 @@ class Level3D extends FileView {
 
 	public function new(state) {
 		super(state);
-		saveDisplayKey = "Level3D:" + getPath().split("\\").join("/").substr(0,-1);
 	}
 
 	override function onDisplay() {
+		saveDisplayKey = "Level3D:" + getPath().split("\\").join("/").substr(0,-1);
 		data = new hide.prefab.l3d.Level3D();
 		var content = sys.io.File.getContent(getPath());
 		data.load(haxe.Json.parse(content));
@@ -234,6 +230,7 @@ class Level3D extends FileView {
 		root.find(".hide-scene-tree").first().append(sceneEditor.tree.root);
 		root.find(".tab").first().append(sceneEditor.properties.root);
 		root.find(".scene").first().append(sceneEditor.scene.root);
+		sceneEditor.tree.root.addClass("small");
 
 		// Level edit
 		{