trethaller 7 سال پیش
والد
کامیت
195737f6ae
1فایلهای تغییر یافته به همراه238 افزوده شده و 0 حذف شده
  1. 238 0
      hide/view/FXScene.hx

+ 238 - 0
hide/view/FXScene.hx

@@ -0,0 +1,238 @@
+package hide.view;
+
+import hide.Element;
+import hide.prefab.Prefab in PrefabElement;
+
+@:access(hide.view.FXScene)
+private class FXSceneEditor extends hide.comp.SceneEditor {
+	var parent : hide.view.FXScene;
+	public function new(view, context, data) {
+		super(view, context, data);
+		parent = cast view;
+	}
+
+	override function onSceneReady() {
+		super.onSceneReady();
+		parent.onSceneReady();
+	}
+
+	override function update(dt) {
+		super.update(dt);
+		parent.onUpdate(dt);
+	}
+
+	override function selectObjects( elts, ?includeTree) {
+		super.selectObjects(elts, includeTree);
+		parent.onSelect(elts);
+	}
+
+	override function getNewContextMenu() {
+		var current = tree.getCurrentOver();
+		var registered = new Array<hide.comp.ContextMenu.ContextMenuItem>();
+		var allRegs = @:privateAccess hide.prefab.Library.registeredElements;
+		var allowed = ["model", "object"];
+		for( ptype in allowed ) {
+			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;
+					}
+
+					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 FXScene extends FileView {
+
+	var sceneEditor : FXSceneEditor;
+	var data : hide.prefab.fx.FXScene;
+	var context : hide.prefab.Context;
+	var tabs : hide.comp.Tabs;
+
+	var tools : hide.comp.Toolbar;
+	var light : h3d.scene.DirLight;
+	var lightDirection = new h3d.Vector( 1, 2, -4 );
+
+
+	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;
+	var currentVersion : Int = 0;
+	var lastSyncChange : Float = 0.;
+	var currentSign : String;
+
+	override function getDefaultContent() {
+		return haxe.io.Bytes.ofString(ide.toJSON(new hide.prefab.fx.FXScene().save()));
+	}
+
+	override function onFileChanged(wasDeleted:Bool) {
+		if( !wasDeleted ) {
+			// double check if content has changed
+			var content = sys.io.File.getContent(getPath());
+			var sign = haxe.crypto.Md5.encode(content);
+			if( sign == currentSign )
+				return;
+		}
+		super.onFileChanged(wasDeleted);
+	}
+
+	override function save() {
+		var content = ide.toJSON(data.save());
+		currentSign = haxe.crypto.Md5.encode(content);
+		sys.io.File.saveContent(getPath(), content);
+	}
+
+	override function onDisplay() {
+		saveDisplayKey = "FX:" + getPath().split("\\").join("/").substr(0,-1);
+		data = new hide.prefab.fx.FXScene();
+		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>
+				<div class="flex">
+					<div class="scene">
+					</div>
+					<div class="tabs">
+						<div class="tab" name="Scene" icon="sitemap">
+							<div class="hide-block">
+								<div class="hide-list hide-scene-tree">
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="fx-animpanel">
+				</div>
+			</div>
+		');
+		tools = new hide.comp.Toolbar(root.find(".toolbar"));
+		tabs = new hide.comp.Tabs(root.find(".tabs"));
+		sceneEditor = new FXSceneEditor(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;
+
+		var animPanel = root.find(".fx-animpanel");
+		var curve = new hide.prefab.Curve();
+		curve.duration = 3.;
+		curve.keys.push({
+			time: 0.1,
+			value: 1.0,
+			prevHandle: {
+				dt: -0.09,
+				dv: -0.1
+			},
+			nextHandle: {
+				dt: 0.12,
+				dv: -0.1
+			},
+		});
+		for(i in 0...2) {
+			curve.keys.push({
+				time: i + 1.0,
+				value: -1.0,
+				prevHandle: {
+					dt: -0.09,
+					dv: -0.1
+				},
+				nextHandle: {
+					dt: 0.3,
+					dv: -0.1
+				},
+			});
+		}
+		var curveAnim = new hide.comp.CurveEditor(animPanel, curve, this.undo);
+	}
+
+	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;
+
+
+		this.saveDisplayKey = "Scene:" + state.path;
+
+		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() ) {
+					m.mainPass.enableLights = false;
+					m.shadows = false;
+				}
+			} else {
+				for( m in context.shared.root3d.getMaterials() )
+					h3d.mat.MaterialSetup.current.initModelMaterial(m);
+			}
+		},true);
+
+		tools.addColor("Background color", function(v) {
+			scene.engine.backgroundColor = v;
+		}, scene.engine.backgroundColor);
+		tools.addToggle("refresh", "Auto synchronize", function(b) {
+			autoSync = b;
+		});
+		tools.addRange("Speed", function(v) {
+			scene.speed = v;
+		}, scene.speed);
+	}
+
+	function onSelect(elts : Array<PrefabElement>) {
+
+	}
+
+	function onUpdate(dt:Float) {
+		var cam = scene.s3d.camera;
+		if( light != null ) {
+			var angle = Math.atan2(cam.target.y - cam.pos.y, cam.target.x - cam.pos.x);
+			light.direction.set(
+				Math.cos(angle) * lightDirection.x - Math.sin(angle) * lightDirection.y,
+				Math.sin(angle) * lightDirection.x + Math.cos(angle) * lightDirection.y,
+				lightDirection.z
+			);
+		}
+		if( autoSync && (currentVersion != undo.currentID || lastSyncChange != properties.lastChange) ) {
+			save();
+			lastSyncChange = properties.lastChange;
+			currentVersion = undo.currentID;
+		}
+	}
+
+	static var _ = FileTree.registerExtension(FXScene,["fx"], { icon : "sitemap", createNew : "FX" });
+}