瀏覽代碼

[animgraph] Root Folder selection, choose preview model

Clément Espeute 8 月之前
父節點
當前提交
8fff478b44

+ 9 - 2
hide/comp/Button.hx

@@ -18,9 +18,16 @@ class Button extends hide.comp.Component {
 		return label;
 	}
 
-	public function new(parent: hide.Element = null, ?label: String, ?options: Options) {
+	public function new(parent: hide.Element = null, element: hide.Element = null, ?label: String, ?options: Options) {
 		options ??= {};
-		super(parent, new Element("<button-2></button-2>"));
+		if (element != null) {
+			if (element.get(0).nodeName != "BUTTON-2")
+				throw "button to wrap must be a <button-2> element";
+		} else {
+			element = new Element("<button-2></button-2>");
+		}
+
+		super(parent, element);
 		labelElem = new Element("<value></value>").appendTo(element);
 
 		this.label = label;

+ 7 - 1
hide/view/GenericGraphEditor.hx

@@ -122,7 +122,9 @@ class GenericGraphEditor extends hide.view.FileView implements IGraphEditor {
         </div>').appendTo(previewContainer);
 		var menu = toolbar.find(".button2");
 
-
+        menu.get(0).onclick = (e: js.html.MouseEvent) -> {
+            hide.comp.ContextMenu.createDropdown(menu.get(0), getPreviewOptionsMenu());
+        }
     }
 
     public function previewFocusObject(obj: h3d.scene.Object) {
@@ -133,6 +135,10 @@ class GenericGraphEditor extends hide.view.FileView implements IGraphEditor {
 		previewCamController.set(sp.r * 3.0, Math.PI / 4, Math.PI * 5 / 13, sp.getCenter());
 	}
 
+    function getPreviewOptionsMenu() : Array<hide.comp.ContextMenu.MenuItem> {
+        return [];
+    }
+
     function onScenePreviewReady() {
         previewCamController = new hide.comp.Scene.PreviewCamController(scenePreview.s3d);
     }

+ 123 - 4
hide/view/animgraph/AnimGraphEditor.hx

@@ -3,6 +3,12 @@ using Lambda;
 import hide.view.GraphInterface;
 import hrt.animgraph.*;
 
+class PreviewSettings {
+    public var modelPath: String = null;
+
+    public function new() {};
+}
+
 @:access(hrt.animgraph.AnimGraph)
 @:access(hrt.animgraph.AnimGraphInstance)
 @:access(hrt.animgraph.Node)
@@ -17,10 +23,36 @@ class AnimGraphEditor extends GenericGraphEditor {
     var previewNode : hrt.animgraph.nodes.AnimNode = null;
     var queuedPreview : hrt.animgraph.nodes.AnimNode = null;
 
+    var previewSettings : PreviewSettings = new PreviewSettings();
+
     override function reloadView() {
         previewNode = null;
         animGraph = cast hide.Ide.inst.loadPrefab(state.path, null,  true);
+
+        if (animGraph.animFolder == null) {
+            element.html("
+                <h1>Choose a folder containing the models to animate</h1>
+                <button-2></button-2>
+            ");
+
+            var button = new hide.comp.Button(null, element.find("button-2"), "Choose folder");
+            button.onClick = () -> {
+                ide.chooseDirectory((path) -> {
+                    if (path != null) {
+                        animGraph.animFolder = path;
+                        save();
+                        reloadView();
+                    }
+                });
+            }
+
+            return;
+        }
+
         super.reloadView();
+        loadPreviewSettings();
+
+
 
         var parameters = new Element("<graph-parameters></graph-parameters>").appendTo(propertiesContainer);
         new Element("<h1>Parameters</h1>").appendTo(parameters);
@@ -57,6 +89,55 @@ class AnimGraphEditor extends GenericGraphEditor {
         });
     }
 
+    function gatherAllPreviewModels() : Array<String> {
+        var paths = [];
+
+        function rec(dirPath: String) {
+            var files = sys.FileSystem.readDirectory(ide.getPath(dirPath));
+            for (path in files) {
+                if (sys.FileSystem.isDirectory(path)) {
+                    rec(dirPath + "/" + path);
+                } else {
+                    var filename = path.split("/").pop();
+                    var ext = filename.split(".").pop();
+
+                    if (ext == "prefab") {
+                        paths.push(dirPath + "/" + path);
+                    }
+                    if (ext == "fbx" && !StringTools.startsWith(filename, "Anim_")) {
+                        paths.push(dirPath + "/" + path);
+                    }
+                }
+            }
+        }
+
+        rec(animGraph.animFolder);
+        return paths;
+    }
+
+    override function getPreviewOptionsMenu() : Array<hide.comp.ContextMenu.MenuItem> {
+        var options = super.getPreviewOptionsMenu();
+
+        var models : Array<hide.comp.ContextMenu.MenuItem> = [];
+        var paths = gatherAllPreviewModels();
+        for (path in paths) {
+            var basePath = StringTools.replace(path, animGraph.animFolder + "/", "");
+            models.push({label: basePath, click: () -> {
+                previewSettings.modelPath = path;
+                savePreviewSettings();
+                reloadPreviewModel();
+            }});
+        }
+
+        options.push({label: "Set Model", menu: models});
+        return options;
+    }
+
+    public function setPreviewMesh(path: String) {
+
+        savePreviewSettings();
+    }
+
     public function refreshPreview() {
         if (previewNode != null)
             setPreview(previewNode);
@@ -273,11 +354,34 @@ class AnimGraphEditor extends GenericGraphEditor {
     override function onScenePreviewReady() {
         super.onScenePreviewReady();
 
-        previewModel = scenePreview.loadModel("Ogre/Ogre_Kobold.fbx");
-        scenePreview.s3d.addChild(previewModel);
+        reloadPreviewModel();
+    }
+
+    function reloadPreviewModel() {
+        if (previewModel != null) {
+            previewModel.remove();
+            previewModel = null;
+        }
 
-        setPreview(cast animGraph.nodes.find((f) -> Std.downcast(f, hrt.animgraph.nodes.Output) != null));
-        resetPreviewCamera();
+        if (previewSettings.modelPath == null)
+            return;
+        try {
+            if (StringTools.endsWith(previewSettings.modelPath, ".prefab")) {
+                throw "todo prefab loading";
+            } else if (StringTools.endsWith(previewSettings.modelPath, ".fbx")) {
+                previewModel =  scenePreview.loadModel(previewSettings.modelPath);
+                scenePreview.s3d.addChild(previewModel);
+                setPreview(cast animGraph.nodes.find((f) -> Std.downcast(f, hrt.animgraph.nodes.Output) != null));
+                resetPreviewCamera();
+            }
+            else {
+                throw "Unsupported model format";
+            }
+        } catch (e) {
+            previewSettings.modelPath = null;
+            ide.quickError("Couldn't load preview : " + e);
+            savePreviewSettings();
+        }
     }
 
     override function getNodes() : Iterator<IGraphNode> {
@@ -413,6 +517,21 @@ class AnimGraphEditor extends GenericGraphEditor {
         previewFocusObject(previewModel);
     }
 
+    public function loadPreviewSettings() {
+		var save = haxe.Json.parse(getDisplayState("previewSettings") ?? "{}");
+		previewSettings = new PreviewSettings();
+		for (f in Reflect.fields(previewSettings)) {
+			var v = Reflect.field(save, f);
+			if (v != null) {
+				Reflect.setField(previewSettings, f, v);
+			}
+		}
+	}
+
+	public function savePreviewSettings() {
+		saveDisplayState("previewSettings", haxe.Json.stringify(previewSettings));
+	}
+
     function addParameter() {
         var newParam = new hrt.animgraph.AnimGraph.Parameter();
         newParam.name = "New Parameter";

+ 5 - 3
hide/view/shadereditor/ShaderEditor.hx

@@ -919,6 +919,10 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
 		}
 	}
 
+	public function savePreviewSettings() {
+		saveDisplayState("previewSettings", haxe.Json.stringify(previewSettings));
+	}
+
 	public function revealParameter(id: Int) : Void {
 		var param = parametersList.find("#param_" + id);
 		parametersList.children().not(param).each((_, elt) -> toggleParameter(new JQuery(elt), false));
@@ -930,9 +934,7 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
 		param.addClass("reveal");
 	}
 
-	public function savePreviewSettings() {
-		saveDisplayState("previewSettings", haxe.Json.stringify(previewSettings));
-	}
+
 
 	public function initMeshPreview() {
 		trace("Init mesh preview");

+ 2 - 0
hrt/animgraph/AnimGraph.hx

@@ -19,6 +19,8 @@ typedef SerializedEdge = {
 @:access(hrt.animgraph.AnimGraphInstance)
 class AnimGraph extends hrt.prefab.Prefab {
 
+	@:s var animFolder : String; // The folder to use as a base for the animation selection/loading
+
 	var nodes: Array<Node> = [];
 	var parameters : Array<Parameter> = [];