|
@@ -166,7 +166,7 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
var meshPreviewRenderProps : hrt.prefab.Prefab;
|
|
|
var meshPreviewRenderPropsRoot : h3d.scene.Object;
|
|
|
|
|
|
- var parametersList : JQuery;
|
|
|
+ var parametersList : hide.comp.FancyArray<hrt.shgraph.ShaderGraph.Parameter>;
|
|
|
var variableList : hide.comp.FancyArray<ShaderGraphVariable>;
|
|
|
|
|
|
var previewElem : Element;
|
|
@@ -229,11 +229,12 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
graphEditor.opBox(inst, true, graphEditor.currentUndoBuffer);
|
|
|
graphEditor.commitUndo();
|
|
|
}
|
|
|
- if (e.dataTransfer.types.contains(variableList.getDragKeyName())) {
|
|
|
- var index = Std.parseInt(e.dataTransfer.getData(variableList.getDragKeyName()));
|
|
|
+
|
|
|
+ var variableIndex = variableList.getDragIndex(e);
|
|
|
+ if (variableIndex != null) {
|
|
|
var hasAnyWrite = false;
|
|
|
shaderGraph.mapShaderVar((v) -> {
|
|
|
- if (v.varId == index && Std.downcast(v, hrt.shgraph.nodes.VarWrite) != null) {
|
|
|
+ if (v.varId == variableIndex && Std.downcast(v, hrt.shgraph.nodes.VarWrite) != null) {
|
|
|
hasAnyWrite = true;
|
|
|
return false;
|
|
|
}
|
|
@@ -242,20 +243,20 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
|
|
|
if (hasAnyWrite) {
|
|
|
var read = new hrt.shgraph.nodes.VarRead();
|
|
|
- read.varId = index;
|
|
|
+ read.varId = variableIndex;
|
|
|
addNode(read);
|
|
|
} else {
|
|
|
hide.comp.ContextMenu.createFromPoint(e.clientX, e.clientY, [{
|
|
|
label: "Write", click: () -> {
|
|
|
var write = new hrt.shgraph.nodes.VarWrite();
|
|
|
- write.varId = index;
|
|
|
+ write.varId = variableIndex;
|
|
|
addNode(write);
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: "Read", click: () -> {
|
|
|
var read = new hrt.shgraph.nodes.VarRead();
|
|
|
- read.varId = index;
|
|
|
+ read.varId = variableIndex;
|
|
|
addNode(read);
|
|
|
}
|
|
|
}]);
|
|
@@ -263,28 +264,33 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- var inst = new ShaderParam();
|
|
|
- inst.parameterId = draggedParamId;
|
|
|
- addNode(inst);
|
|
|
+ var paramIndex = parametersList.getDragIndex(e);
|
|
|
+ if (paramIndex != null) {
|
|
|
+ var inst = new ShaderParam();
|
|
|
+ inst.parameterId = paramIndex;
|
|
|
+ addNode(inst);
|
|
|
+ return;
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
var rightPannel = new Element(
|
|
|
'<div id="rightPanel">
|
|
|
<div class="hide-block flexible" >
|
|
|
- <span>Parameters</span>
|
|
|
+ <h1 class="subtle-title">Parameters</h1 class="subtle-title">
|
|
|
|
|
|
- <div id="parametersList" class="hide-scene-tree hide-list">
|
|
|
- </div>
|
|
|
+ <fancy-array class="parameters merge-bottom" style="flex-grow: 1">
|
|
|
|
|
|
- <input id="createParameter" type="button" value="Add parameter" />
|
|
|
+ </fancy-array>
|
|
|
+ <fancy-button class="fancy-small createParameter merge-top"><div class="icon ico ico-plus"></div></fancy-button>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="hide-block flexible" >
|
|
|
- <fancy-array class="variables" style="flex-grow: 1">
|
|
|
+ <h1 class="subtle-title">Variables</h1 class="subtle-title">
|
|
|
+ <fancy-array class="variables merge-bottom" style="flex-grow: 1">
|
|
|
|
|
|
</fancy-array>
|
|
|
- <fancy-button class="fancy-small add-variable">Add Variable</fancy-button>
|
|
|
+ <fancy-button class="fancy-small add-variable merge-top"><div class="icon ico ico-plus"></div></fancy-button>
|
|
|
</div>
|
|
|
|
|
|
<div class="options-block hide-block">
|
|
@@ -309,37 +315,58 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
variableList.removeItem = removeVariable;
|
|
|
variableList.setItemName = renameVariable;
|
|
|
variableList.getItemContent = getVariableContent;
|
|
|
+ variableList.customizeHeader = (v:ShaderGraphVariable, header:Element) -> {
|
|
|
+ var type = switch(v.type) {
|
|
|
+ case SgFloat(1): "Float";
|
|
|
+ case SgFloat(n): "Vec " + n;
|
|
|
+ case SgSampler: "Texture";
|
|
|
+ case SgInt: "Int";
|
|
|
+ case SgBool: "Bool";
|
|
|
+ default: "Unknown Type";
|
|
|
+ };
|
|
|
+ header.find("input").after(new Element('<div class="type">$type</div>'));
|
|
|
+ }
|
|
|
|
|
|
variableList.refresh();
|
|
|
|
|
|
var addVariable = rightPannel.find(".add-variable");
|
|
|
+ var createVariableMenu : Array<hide.comp.ContextMenu.MenuItem> = [
|
|
|
+ {
|
|
|
+ label: "Int",
|
|
|
+ click: () -> createVariable(SgInt),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Float",
|
|
|
+ click: () -> createVariable(SgFloat(1)),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Vec 2",
|
|
|
+ click: () -> createVariable(SgFloat(2)),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Vec 3",
|
|
|
+ click: () -> createVariable(SgFloat(3)),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Vec 4",
|
|
|
+ click: () -> createVariable(SgFloat(4)),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "Color",
|
|
|
+ click: () -> createVariable(SgFloat(4), true),
|
|
|
+ },
|
|
|
+ ];
|
|
|
+
|
|
|
addVariable.on("click", (e) -> {
|
|
|
- hide.comp.ContextMenu.createDropdown(addVariable.get(0), [
|
|
|
- {
|
|
|
- label: "Int",
|
|
|
- click: () -> createVariable(SgInt),
|
|
|
- },
|
|
|
- {
|
|
|
- label: "Float",
|
|
|
- click: () -> createVariable(SgFloat(1)),
|
|
|
- },
|
|
|
- {
|
|
|
- label: "Vec 2",
|
|
|
- click: () -> createVariable(SgFloat(2)),
|
|
|
- },
|
|
|
- {
|
|
|
- label: "Vec 3",
|
|
|
- click: () -> createVariable(SgFloat(3)),
|
|
|
- },
|
|
|
- {
|
|
|
- label: "Vec 4",
|
|
|
- click: () -> createVariable(SgFloat(4)),
|
|
|
- },
|
|
|
- {
|
|
|
- label: "Color",
|
|
|
- click: () -> createVariable(SgFloat(4), true),
|
|
|
- },
|
|
|
- ]);
|
|
|
+ hide.comp.ContextMenu.createDropdown(addVariable.get(0), createVariableMenu);
|
|
|
+ });
|
|
|
+
|
|
|
+ variableList.element.on("contextmenu", function(e) {
|
|
|
+ e.preventDefault();
|
|
|
+ e.stopPropagation();
|
|
|
+ var vars = createVariableMenu.copy();
|
|
|
+ vars.unshift({label:"New", isSeparator: true});
|
|
|
+ hide.comp.ContextMenu.createFromEvent(e.originalEvent, vars);
|
|
|
});
|
|
|
|
|
|
rightPannel.find("#centerView").click((e) -> graphEditor.centerView());
|
|
@@ -377,27 +404,44 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
{ label : "Texture", click : () -> createParameter(HxslType.TSampler(T2D,false)) },
|
|
|
];
|
|
|
|
|
|
- var createParameter = rightPannel.find("#createParameter");
|
|
|
- createParameter.on("click", function() {
|
|
|
+ var createParameter = rightPannel.find(".createParameter");
|
|
|
+ createParameter.on("click", function(e) {
|
|
|
hide.comp.ContextMenu.createDropdown(createParameter.get(0), newParamCtxMenu);
|
|
|
});
|
|
|
|
|
|
- parametersList = rightPannel.find("#parametersList");
|
|
|
- parametersList.on("contextmenu", function(e) {
|
|
|
+
|
|
|
+ parametersList = new hide.comp.FancyArray(null, rightPannel.find(".parameters"), "parameters", "parameters");
|
|
|
+ parametersList.element.on("contextmenu", function(e) {
|
|
|
e.preventDefault();
|
|
|
e.stopPropagation();
|
|
|
- hide.comp.ContextMenu.createFromEvent(cast e, [
|
|
|
- {
|
|
|
- label : "Add Parameter",
|
|
|
- menu : newParamCtxMenu,
|
|
|
- },
|
|
|
- ]);
|
|
|
+ var params = newParamCtxMenu.copy();
|
|
|
+ params.unshift({label:"New", isSeparator: true});
|
|
|
+ hide.comp.ContextMenu.createFromEvent(e.originalEvent, params);
|
|
|
});
|
|
|
|
|
|
- for (k in shaderGraph.parametersKeys) {
|
|
|
- var pElt = addParameter(shaderGraph.parametersAvailable.get(k), shaderGraph.parametersAvailable.get(k).defaultValue);
|
|
|
+ parametersList.getItems = () -> {
|
|
|
+ var values = shaderGraph.parametersAvailable.array();
|
|
|
+ values.sort((a, b) -> Reflect.compare(a.index, b.index));
|
|
|
+ return values;
|
|
|
+ };
|
|
|
+ parametersList.getItemName = (v: Parameter) -> v.name;
|
|
|
+ parametersList.reorderItem = reorderParameter;
|
|
|
+ parametersList.removeItem = removeParameter;
|
|
|
+ parametersList.setItemName = renameParameter;
|
|
|
+ parametersList.getItemContent = getParameterContent;
|
|
|
+ parametersList.customizeHeader = (p:Parameter, header:Element) -> {
|
|
|
+ var type = switch(p.type) {
|
|
|
+ case TFloat: "Number";
|
|
|
+ case TVec(4, VFloat): "Color";
|
|
|
+ case TVec(1, VFloat): "Float";
|
|
|
+ case TVec(n, VFloat): "Vec " + n;
|
|
|
+ case TSampler(_): "Texture";
|
|
|
+ default: "Unknown Type";
|
|
|
+ };
|
|
|
+ header.find("input").after(new Element('<div class="type">$type</div>'));
|
|
|
}
|
|
|
|
|
|
+ parametersList.refresh();
|
|
|
|
|
|
rightPannel.find("#debugMenu").click((e) -> {
|
|
|
hide.comp.ContextMenu.createDropdown(rightPannel.find("#debugMenu").get(0), [
|
|
@@ -534,6 +578,7 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
}
|
|
|
exec(false);
|
|
|
undo.change(Custom(exec));
|
|
|
+ variableList.editTitle(shaderGraph.variables.length-1);
|
|
|
}
|
|
|
|
|
|
var validNameCheck = ~/^[_a-zA-Z][_a-zA-Z0-9]*$/;
|
|
@@ -546,6 +591,12 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ if (shaderGraph.variables.find(v -> v != variable && v.name == newName) != null) {
|
|
|
+ variableList.refresh();
|
|
|
+ ide.quickError('Variable name "$newName" already exist in this shadergraph');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
var oldName = variable.name;
|
|
|
function exec(isUndo: Bool) {
|
|
|
variable.name = !isUndo ? newName : oldName;
|
|
@@ -705,91 +756,41 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
undo.change(Custom(exec));
|
|
|
}
|
|
|
|
|
|
- function createParameter(type : HxslType) {
|
|
|
- @:privateAccess var paramShaderID : Int = shaderGraph.current_param_id++;
|
|
|
- @:privateAccess
|
|
|
- function exec(isUndo:Bool) {
|
|
|
- if (!isUndo) {
|
|
|
- var name = "Param_" + paramShaderID;
|
|
|
- shaderGraph.parametersAvailable.set(paramShaderID, {id: paramShaderID, name : name, type : type, defaultValue : null, variable : shaderGraph.generateParameter(name, type), index : shaderGraph.parametersKeys.length});
|
|
|
- shaderGraph.parametersKeys.push(paramShaderID);
|
|
|
+ function renameParameter(item: Parameter, name: String) : Void {
|
|
|
+ if (!validNameCheck.match(name))
|
|
|
+ {
|
|
|
+ parametersList.refresh();
|
|
|
+ ide.quickError('"$name" is not a valid parameter name (must start with _ or a letter, and only contains letters, numbers and underscores)');
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- var paramShader = shaderGraph.getParameter(paramShaderID);
|
|
|
- var elt = addParameter(paramShader, null);
|
|
|
- elt.find(".input-title").focus();
|
|
|
- } else {
|
|
|
- shaderGraph.parametersAvailable.remove(paramShaderID);
|
|
|
- shaderGraph.parametersKeys.remove(paramShaderID);
|
|
|
- parametersUpdate.remove(paramShaderID);
|
|
|
- shaderGraph.checkParameterIndex();
|
|
|
- parametersList.find("#param_" + paramShaderID).remove();
|
|
|
- }
|
|
|
+ if (shaderGraph.parametersAvailable.find(p -> p != item && p.name == name) != null) {
|
|
|
+ parametersList.refresh();
|
|
|
+ ide.quickError('Parameter name "$name" already exist in this shadergraph');
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
+ var oldName = item.name;
|
|
|
+ function exec(isUndo: Bool) {
|
|
|
+ item.name = !isUndo ? name : oldName;
|
|
|
+ item.variable.name = item.name;
|
|
|
+ for (node in currentGraph.nodes) {
|
|
|
+ var param = Std.downcast(node, ShaderParam);
|
|
|
+ if (param == null)
|
|
|
+ continue;
|
|
|
+ graphEditor.refreshBox(node.id);
|
|
|
+ }
|
|
|
+ requestRecompile();
|
|
|
+ parametersList.refresh();
|
|
|
+ }
|
|
|
exec(false);
|
|
|
undo.change(Custom(exec));
|
|
|
}
|
|
|
|
|
|
- function moveParameter(parameter : Parameter, up : Bool) {
|
|
|
- var parameterElt = parametersList.find("#param_" + parameter.id);
|
|
|
- var parameterPrev = shaderGraph.parametersAvailable.get(shaderGraph.parametersKeys[shaderGraph.parametersKeys.indexOf(parameter.id) + (up? -1 : 1)]);
|
|
|
- execMoveParameterTo(parameter, parameterPrev, !up);
|
|
|
- }
|
|
|
-
|
|
|
- function updateParam(id : Int) : Bool {
|
|
|
- meshPreviewScene.setCurrent(); // needed for texture changes
|
|
|
-
|
|
|
- var param = shaderGraph.getParameter(id);
|
|
|
- var init = compiledShader.inits.find((i) -> i.variable.name == param.name);
|
|
|
- if (init != null) {
|
|
|
- setParamValue(meshPreviewShader, init.variable, param.defaultValue);
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- var parametersUpdate : Map<Int, (Dynamic) -> Void> = [];
|
|
|
-
|
|
|
- function addParameter(parameter : Parameter, ?value : Dynamic) {
|
|
|
-
|
|
|
- var elt = new Element('<div id="param_${parameter.id}" class="parameter" draggable="true"></div>').appendTo(parametersList);
|
|
|
- elt.on("click", function(e) {e.stopPropagation();});
|
|
|
- elt.on("contextmenu", function(e) {
|
|
|
- var elements = [];
|
|
|
- e.stopPropagation();
|
|
|
- var newCtxMenu : Array<hide.comp.ContextMenu.MenuItem> = [
|
|
|
- { label: "Select Nodes", click : () -> {
|
|
|
- var list : Array<IGraphNode> = [];
|
|
|
- for (node in currentGraph.getNodes()) {
|
|
|
- var param = Std.downcast(node, ShaderParam);
|
|
|
- if (param != null && param.parameterId == parameter.id) {
|
|
|
- list.push(param);
|
|
|
- }
|
|
|
- }
|
|
|
- graphEditor.setSelection(list);
|
|
|
- graphEditor.centerSelection();
|
|
|
- }},
|
|
|
- { isSeparator: true},
|
|
|
- { label : "Move up", click : () -> {
|
|
|
- //beforeChange();
|
|
|
- moveParameter(parameter, true);
|
|
|
- //afterChange();
|
|
|
- }, enabled: shaderGraph.parametersKeys.indexOf(parameter.id) > 0},
|
|
|
- { label : "Move down", click : () -> {
|
|
|
- //beforeChange();
|
|
|
- moveParameter(parameter, false);
|
|
|
- //afterChange();
|
|
|
- }, enabled: shaderGraph.parametersKeys.indexOf(parameter.id) < shaderGraph.parametersKeys.length-1}
|
|
|
- ];
|
|
|
- hide.comp.ContextMenu.createFromEvent(cast e, newCtxMenu);
|
|
|
- e.preventDefault();
|
|
|
-
|
|
|
- });
|
|
|
+ function getParameterContent(parameter: Parameter) : Element {
|
|
|
var content = new Element('<div class="content" ></div>');
|
|
|
- content.hide();
|
|
|
- var defaultValue = new Element("<div><span>Default: </span></div>").appendTo(content);
|
|
|
+ var defaultValue = new Element('<div class="values"><span>Default: </span></div>').appendTo(content);
|
|
|
|
|
|
- var typeName = "";
|
|
|
switch(parameter.type) {
|
|
|
case TFloat:
|
|
|
var parentRange = new Element('<input type="range" min="-1" max="1" />').appendTo(defaultValue);
|
|
@@ -797,19 +798,9 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
var rangeInput = @:privateAccess range.f;
|
|
|
|
|
|
var save : Null<Float> = null;
|
|
|
- rangeInput.on("mousedown", function(e) {
|
|
|
- elt.attr("draggable", "false");
|
|
|
- //beforeChange();
|
|
|
- });
|
|
|
- rangeInput.on("mouseup", function(e) {
|
|
|
- elt.attr("draggable", "true");
|
|
|
- //afterChange();
|
|
|
- });
|
|
|
- if (value == null) value = 0;
|
|
|
- range.value = value;
|
|
|
|
|
|
- parametersUpdate.set(parameter.id, (v:Dynamic) -> range.value = v);
|
|
|
- shaderGraph.setParameterDefaultValue(parameter.id, value);
|
|
|
+ if (parameter.defaultValue == null) parameter.defaultValue = 0;
|
|
|
+ range.value = parameter.defaultValue;
|
|
|
|
|
|
var saveValue : Null<Float> = null;
|
|
|
range.onChange = function(moving) {
|
|
@@ -823,8 +814,8 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
saveValue = null;
|
|
|
function exec(isUndo : Bool) {
|
|
|
var v = isUndo ? old : curr;
|
|
|
- shaderGraph.setParameterDefaultValue(parameter.id, v);
|
|
|
- parametersUpdate[parameter.id](v);
|
|
|
+ parameter.defaultValue = v;
|
|
|
+ range.value = v;
|
|
|
updateParam(parameter.id);
|
|
|
}
|
|
|
exec(false);
|
|
@@ -836,20 +827,15 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
return;
|
|
|
updateParam(parameter.id);
|
|
|
};
|
|
|
- typeName = "Number";
|
|
|
case TVec(4, VFloat):
|
|
|
var parentPicker = new Element('<div style="width: 35px; height: 25px; display: inline-block;"></div>').appendTo(defaultValue);
|
|
|
var picker = new hide.comp.ColorPicker.ColorBox(null, parentPicker, true, true);
|
|
|
|
|
|
-
|
|
|
- if (value == null)
|
|
|
- value = [0, 0, 0, 1];
|
|
|
- var start : h3d.Vector = h3d.Vector.fromArray(value);
|
|
|
- shaderGraph.setParameterDefaultValue(parameter.id, value);
|
|
|
+ if (parameter.defaultValue == null)
|
|
|
+ parameter.defaultValue = [0, 0, 0, 1];
|
|
|
+ var start : h3d.Vector = h3d.Vector.fromArray(parameter.defaultValue);
|
|
|
picker.value = start.toColor();
|
|
|
|
|
|
- parametersUpdate.set(parameter.id, (v:Dynamic) -> picker.value = v.toColor());
|
|
|
-
|
|
|
var saveValue : Null<h3d.Vector4> = null;
|
|
|
picker.onChange = function(move) {
|
|
|
if (saveValue == null) {
|
|
@@ -862,8 +848,8 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
saveValue = null;
|
|
|
function exec(isUndo : Bool) {
|
|
|
var v = isUndo ? old : curr;
|
|
|
- parametersUpdate[parameter.id](v);
|
|
|
- shaderGraph.setParameterDefaultValue(parameter.id, [v.x, v.y, v.z, v.w]);
|
|
|
+ picker.value = v.toColor();
|
|
|
+ parameter.defaultValue = [v.x, v.y, v.z, v.w];
|
|
|
updateParam(parameter.id);
|
|
|
}
|
|
|
exec(false);
|
|
@@ -876,14 +862,10 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
//setBoxesParam(parameter.id);
|
|
|
updateParam(parameter.id);
|
|
|
};
|
|
|
- typeName = "Color";
|
|
|
case TVec(n, VFloat):
|
|
|
- if (value == null)
|
|
|
- value = [for (i in 0...n) 0.0];
|
|
|
-
|
|
|
- shaderGraph.setParameterDefaultValue(parameter.id, value);
|
|
|
+ if (parameter.defaultValue == null)
|
|
|
+ parameter.defaultValue = [for (i in 0...n) 0.0];
|
|
|
|
|
|
- //var row = new Element('<div class="flex"/>').appendTo(defaultValue);
|
|
|
|
|
|
var ranges : Array<hide.comp.Range> = [];
|
|
|
|
|
@@ -893,17 +875,9 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
var parentRange = new Element('<input type="range" min="-1" max="1" />').appendTo(defaultValue);
|
|
|
var range = new hide.comp.Range(null, parentRange);
|
|
|
ranges.push(range);
|
|
|
- range.value = value[i];
|
|
|
+ range.value = parameter.defaultValue[i];
|
|
|
|
|
|
var rangeInput = @:privateAccess range.f;
|
|
|
- rangeInput.on("mousedown", function(e) {
|
|
|
- elt.attr("draggable", "false");
|
|
|
- //beforeChange();
|
|
|
- });
|
|
|
- rangeInput.on("mouseup", function(e) {
|
|
|
- elt.attr("draggable", "true");
|
|
|
- //afterChange();
|
|
|
- });
|
|
|
|
|
|
range.onChange = function(move) {
|
|
|
if (saveValue == null) {
|
|
@@ -916,8 +890,11 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
saveValue = null;
|
|
|
function exec(isUndo : Bool) {
|
|
|
var v = isUndo ? old : curr;
|
|
|
+ parameter.defaultValue = parameter.id;
|
|
|
shaderGraph.setParameterDefaultValue(parameter.id, v);
|
|
|
- parametersUpdate[parameter.id](v);
|
|
|
+ for (i in 0 ... n)
|
|
|
+ ranges[i].value = v[i];
|
|
|
+
|
|
|
updateParam(parameter.id);
|
|
|
}
|
|
|
exec(false);
|
|
@@ -925,34 +902,19 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- value[i] = range.value;
|
|
|
- if (!shaderGraph.setParameterDefaultValue(parameter.id, value))
|
|
|
- return;
|
|
|
- //setBoxesParam(parameter.id);
|
|
|
+ parameter.defaultValue[i] = range.value;
|
|
|
updateParam(parameter.id);
|
|
|
};
|
|
|
- //if(min == null) min = isColor ? 0.0 : -1.0;
|
|
|
- //if(max == null) max = 1.0;
|
|
|
- //e.attr("min", "" + min);
|
|
|
- //e.attr("max", "" + max);
|
|
|
}
|
|
|
- parametersUpdate.set(parameter.id, (v:Dynamic) -> {
|
|
|
- for (i in 0...n) {
|
|
|
- ranges[i].value = v[i];
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- typeName = "Vec" + n;
|
|
|
case TSampler(_):
|
|
|
var parentSampler = new Element('<input type="texturepath" field="sampler2d"/>').appendTo(defaultValue);
|
|
|
|
|
|
var tselect = new hide.comp.TextureChoice(null, parentSampler);
|
|
|
- parametersUpdate.set(parameter.id, (v:Dynamic) -> tselect.value = v);
|
|
|
var saveValue : String = null;
|
|
|
- tselect.value = value;
|
|
|
+ tselect.value = parameter.defaultValue;
|
|
|
tselect.onChange = function(notTmpChange: Bool) {
|
|
|
if (saveValue == null) {
|
|
|
- saveValue = haxe.Json.stringify(shaderGraph.parametersAvailable.get(parameter.id).defaultValue);
|
|
|
+ saveValue = haxe.Json.stringify(parameter.defaultValue);
|
|
|
}
|
|
|
var currentValue = haxe.Json.parse(haxe.Json.stringify(tselect.value));
|
|
|
if (notTmpChange) {
|
|
@@ -961,8 +923,8 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
var curr = currentValue;
|
|
|
function exec(isUndo: Bool) {
|
|
|
var v = !isUndo ? curr : prev;
|
|
|
- shaderGraph.setParameterDefaultValue(parameter.id, v);
|
|
|
- parametersUpdate[parameter.id](v);
|
|
|
+ parameter.defaultValue = v;
|
|
|
+ tselect.value = v;
|
|
|
|
|
|
if (!updateParam(parameter.id)) {
|
|
|
// If the graph was initialised without the variable,
|
|
@@ -982,19 +944,10 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
requestRecompile();
|
|
|
}
|
|
|
}
|
|
|
- typeName = "Texture";
|
|
|
|
|
|
default:
|
|
|
}
|
|
|
|
|
|
- var header = new Element('<div class="header">
|
|
|
- <i class="ico ico-angle-right" ></i>
|
|
|
- <input class="input-title" type="input" value="${parameter.name}" />
|
|
|
- <div class="type">
|
|
|
- ${typeName}
|
|
|
- </div>
|
|
|
- </div>');
|
|
|
-
|
|
|
var internal = new Element('<div><input type="checkbox" name="internal" id="internal"></input><label for="internal">Internal</label><div>').appendTo(content).find("#internal");
|
|
|
internal.prop("checked", parameter.internal ?? false);
|
|
|
|
|
@@ -1006,13 +959,6 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
|
|
|
var perInstanceCb = new Element('<div><input type="checkbox" name="perinstance"/><label for="perinstance">Per instance</label><div>');
|
|
|
var shaderParams : Array<ShaderParam> = [];
|
|
|
- // for (b in listOfBoxes) {
|
|
|
- // var tmpShaderParam = Std.downcast(b.getInstance(), ShaderParam);
|
|
|
- // if (tmpShaderParam != null && tmpShaderParam.parameterId == parameter.id) {
|
|
|
- // shaderParams.push(tmpShaderParam);
|
|
|
- // break;
|
|
|
- // }
|
|
|
- // }
|
|
|
|
|
|
var checkbox = perInstanceCb.find("input");
|
|
|
if (shaderParams.length > 0)
|
|
@@ -1027,137 +973,141 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
});
|
|
|
perInstanceCb.appendTo(content);
|
|
|
|
|
|
- header.appendTo(elt);
|
|
|
- content.appendTo(elt);
|
|
|
- var actionBtns = new Element('<div class="action-btns" ></div>').appendTo(content);
|
|
|
- var deleteBtn = new Element('<input type="button" value="Delete" />');
|
|
|
- deleteBtn.on("click", function() {
|
|
|
- @:privateAccess
|
|
|
- for (graph in shaderGraph.graphs) {
|
|
|
- for (node in graph.getNodes()) {
|
|
|
- var shaderParam = Std.downcast(node, ShaderParam);
|
|
|
- if (shaderParam != null && shaderParam.parameterId == parameter.id) {
|
|
|
- Ide.inst.quickError("This parameter is used in the graph.");
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ return content;
|
|
|
|
|
|
- function exec(isUndo : Bool) {
|
|
|
- if (!isUndo) {
|
|
|
- shaderGraph.parametersAvailable.remove(parameter.id);
|
|
|
- shaderGraph.parametersKeys.remove(parameter.id);
|
|
|
- parametersUpdate.remove(parameter.id);
|
|
|
- shaderGraph.checkParameterIndex();
|
|
|
- elt.remove();
|
|
|
- } else {
|
|
|
- shaderGraph.parametersAvailable.set(parameter.id, parameter);
|
|
|
- shaderGraph.parametersKeys.insert(parameter.index, parameter.id);
|
|
|
- shaderGraph.checkParameterIndex();
|
|
|
+ }
|
|
|
|
|
|
- updateParam(parameter.id);
|
|
|
- addParameter(parameter, parameter.defaultValue);
|
|
|
+ function reorderParameter(oldIndex: Int, newIndex: Int) {
|
|
|
+ var oldIndexes: Map<Int, Int> = [];
|
|
|
+ for (idx => param in shaderGraph.parametersAvailable) {
|
|
|
+ oldIndexes[idx] = param.index;
|
|
|
+ }
|
|
|
+
|
|
|
+ function exec(isUndo: Bool) {
|
|
|
+ if (!isUndo) {
|
|
|
+ for (param in shaderGraph.parametersAvailable) {
|
|
|
+ if (param.index == oldIndex) {
|
|
|
+ param.index = newIndex;
|
|
|
+ } else {
|
|
|
+ if (param.index >= oldIndex) {
|
|
|
+ param.index --;
|
|
|
+ }
|
|
|
|
|
|
- for (id in shaderGraph.parametersKeys) {
|
|
|
- var newElt = parametersList.find("#param_" + id);
|
|
|
- parametersList.append(newElt);
|
|
|
+ if (param.index >= newIndex) {
|
|
|
+ param.index ++;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ } else {
|
|
|
+ for (i => param in shaderGraph.parametersAvailable) {
|
|
|
+ param.index = oldIndexes[i];
|
|
|
+ }
|
|
|
}
|
|
|
- exec(false);
|
|
|
- undo.change(Custom(exec));
|
|
|
- });
|
|
|
- deleteBtn.appendTo(actionBtns);
|
|
|
-
|
|
|
+ parametersList.refresh();
|
|
|
+ }
|
|
|
+ exec(false);
|
|
|
+ undo.change(Custom(exec));
|
|
|
+ }
|
|
|
|
|
|
+ function removeParameter(orderIndex: Int) {
|
|
|
+ var param = null;
|
|
|
+ var index = null;
|
|
|
+ for (iterIndex => iterParam in shaderGraph.parametersAvailable) {
|
|
|
+ if (iterParam.index == orderIndex) {
|
|
|
+ param = iterParam;
|
|
|
+ index = iterIndex;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- var inputTitle = elt.find(".input-title");
|
|
|
- inputTitle.on("click", function(e) {
|
|
|
- e.stopPropagation();
|
|
|
- });
|
|
|
- inputTitle.on("keydown", function(e) {
|
|
|
- e.stopPropagation();
|
|
|
- });
|
|
|
- inputTitle.on("change", function(e) {
|
|
|
- var newName = inputTitle.val();
|
|
|
- if (!validNameCheck.match(newName)) {
|
|
|
- ide.quickError('"$newName" is not a valid variable name (must start with _ or a letter, and only contains letters, numbers and underscores)');
|
|
|
- inputTitle.val(parameter.name);
|
|
|
- return;
|
|
|
+ var canBeDeleted = true;
|
|
|
+ for (graph in shaderGraph.graphs) {
|
|
|
+ for (node in graph.nodes) {
|
|
|
+ var param = Std.downcast(node, ShaderParam);
|
|
|
+ if (param == null)
|
|
|
+ continue;
|
|
|
+ if (param.parameterId == index) {
|
|
|
+ canBeDeleted = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
+ if (!canBeDeleted)
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- var prevName = parameter.name;
|
|
|
- var exec = function(isUndo : Bool) {
|
|
|
- var v = !isUndo ? newName : prevName;
|
|
|
- shaderGraph.setParameterTitle(parameter.id, v);
|
|
|
- inputTitle.val(v);
|
|
|
+ if (!canBeDeleted) {
|
|
|
+ ide.quickError("Paramter " + param.name + " is used in the graph and can't be deleted");
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- requestRecompile();
|
|
|
+ function exec(isUndo: Bool) {
|
|
|
+ if (!isUndo) {
|
|
|
+ shaderGraph.parametersAvailable.remove(index);
|
|
|
|
|
|
- for (id => node in currentGraph.getNodes()) {
|
|
|
- if (Std.downcast(node, ShaderParam) != null) {
|
|
|
- graphEditor.refreshBox(id);
|
|
|
+ for (param in shaderGraph.parametersAvailable) {
|
|
|
+ if (param.index > orderIndex) {
|
|
|
+ param.index --;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ for (param in shaderGraph.parametersAvailable) {
|
|
|
+ if (param.index >= orderIndex) {
|
|
|
+ param.index ++;
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- exec(false);
|
|
|
- undo.change(Custom(exec));
|
|
|
- inputTitle.blur();
|
|
|
-
|
|
|
-
|
|
|
- // if (shaderGraph.setParameterTitle(parameter.id, newName)) {
|
|
|
- // for (b in listOfBoxes) {
|
|
|
- // var shaderParam = Std.downcast(b.getInstance(), ShaderParam);
|
|
|
- // if (shaderParam != null && shaderParam.parameterId == parameter.id) {
|
|
|
- // beforeChange();
|
|
|
- // shaderParam.setName(newName);
|
|
|
- // afterChange();
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
- });
|
|
|
- inputTitle.on("focus", function() { inputTitle.select(); } );
|
|
|
+ shaderGraph.parametersAvailable.set(index, param);
|
|
|
+ }
|
|
|
|
|
|
- elt.find(".header").on("click", function() {
|
|
|
- toggleParameter(elt);
|
|
|
- });
|
|
|
+ parametersList.refresh();
|
|
|
+ }
|
|
|
|
|
|
- elt.on("dragstart", function(e) {
|
|
|
- draggedParamId = parameter.id;
|
|
|
- });
|
|
|
+ exec(false);
|
|
|
+ undo.change(Custom(exec));
|
|
|
+ }
|
|
|
|
|
|
- inline function isAfter(e) {
|
|
|
- return e.clientY > (elt.offset().top + elt.outerHeight() / 2.0);
|
|
|
+ function createParameter(type : HxslType) {
|
|
|
+ @:privateAccess var paramShaderID : Int = shaderGraph.current_param_id++;
|
|
|
+ @:privateAccess
|
|
|
+ function exec(isUndo:Bool) {
|
|
|
+ if (!isUndo) {
|
|
|
+ var name = "Param_" + paramShaderID;
|
|
|
+ shaderGraph.parametersAvailable.set(paramShaderID, {id: paramShaderID, name : name, type : type, defaultValue : null, variable : shaderGraph.generateParameter(name, type), index : shaderGraph.parametersKeys.length});
|
|
|
+ shaderGraph.parametersKeys.push(paramShaderID);
|
|
|
+ } else {
|
|
|
+ shaderGraph.parametersAvailable.remove(paramShaderID);
|
|
|
+ shaderGraph.parametersKeys.remove(paramShaderID);
|
|
|
+ parametersUpdate.remove(paramShaderID);
|
|
|
+ shaderGraph.checkParameterIndex();
|
|
|
+ }
|
|
|
+ parametersList.refresh();
|
|
|
}
|
|
|
|
|
|
- elt.on("dragover", function(e : js.jquery.Event) {
|
|
|
- var after = isAfter(e);
|
|
|
- elt.toggleClass("hovertop", !after);
|
|
|
- elt.toggleClass("hoverbot", after);
|
|
|
- e.preventDefault();
|
|
|
- });
|
|
|
-
|
|
|
- elt.on("dragleave", function(e) {
|
|
|
- elt.toggleClass("hovertop", false);
|
|
|
- elt.toggleClass("hoverbot", false);
|
|
|
- });
|
|
|
+ exec(false);
|
|
|
+ undo.change(Custom(exec));
|
|
|
+ var paramShader = shaderGraph.getParameter(paramShaderID);
|
|
|
+ parametersList.editTitle(paramShader.index);
|
|
|
+ }
|
|
|
|
|
|
- elt.on("dragenter", function(e) {
|
|
|
- e.preventDefault();
|
|
|
- });
|
|
|
+ // function moveParameter(parameter : Parameter, up : Bool) {
|
|
|
+ // var parameterElt = parametersList.find("#param_" + parameter.id);
|
|
|
+ // var parameterPrev = shaderGraph.parametersAvailable.get(shaderGraph.parametersKeys[shaderGraph.parametersKeys.indexOf(parameter.id) + (up? -1 : 1)]);
|
|
|
+ // execMoveParameterTo(parameter, parameterPrev, !up);
|
|
|
+ // }
|
|
|
|
|
|
- elt.on("drop", function(e) {
|
|
|
- elt.toggleClass("hovertop", false);
|
|
|
- elt.toggleClass("hoverbot", false);
|
|
|
- var other = shaderGraph.getParameter(draggedParamId);
|
|
|
- var after = isAfter(e);
|
|
|
- execMoveParameterTo(other, parameter, after);
|
|
|
- });
|
|
|
+ function updateParam(id : Int) : Bool {
|
|
|
+ meshPreviewScene.setCurrent(); // needed for texture changes
|
|
|
|
|
|
- return elt;
|
|
|
+ var param = shaderGraph.getParameter(id);
|
|
|
+ var init = compiledShader.inits.find((i) -> i.variable.name == param.name);
|
|
|
+ if (init != null) {
|
|
|
+ setParamValue(meshPreviewShader, init.variable, param.defaultValue);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
+ var parametersUpdate : Map<Int, (Dynamic) -> Void> = [];
|
|
|
+
|
|
|
function toggleParameter( elt : JQuery, ?b : Bool) {
|
|
|
var icon = elt.find(".ico");
|
|
|
if (b == null) {
|
|
@@ -1171,45 +1121,6 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
icon.toggleClass("fa-rotate-90", b);
|
|
|
}
|
|
|
|
|
|
- function execMoveParameterTo(paramA: Parameter, paramB: Parameter, after: Bool) {
|
|
|
- var oldIndex = paramA.index;
|
|
|
- var newIndex = paramB.index;
|
|
|
- var delta = newIndex - oldIndex;
|
|
|
- if (delta == 0)
|
|
|
- return;
|
|
|
-
|
|
|
- if (after && delta < 0)
|
|
|
- delta += 1;
|
|
|
- if (!after && delta > 0)
|
|
|
- delta -= 1;
|
|
|
-
|
|
|
- function exec(isUndo: Bool) {
|
|
|
- moveParameterOffset(paramA, isUndo ? -delta : delta);
|
|
|
- }
|
|
|
- exec(false);
|
|
|
- undo.change(Custom(exec));
|
|
|
- }
|
|
|
-
|
|
|
- function moveParameterOffset(paramA: Parameter, offset: Int) {
|
|
|
- var current = paramA.index;
|
|
|
- var end = current + offset;
|
|
|
- var dir = offset > 0 ? 1 : -1;
|
|
|
- while(current != end) {
|
|
|
- var next = current + dir;
|
|
|
- var tmp = shaderGraph.parametersKeys[current];
|
|
|
- shaderGraph.parametersKeys[current] = shaderGraph.parametersKeys[next];
|
|
|
- shaderGraph.parametersKeys[next] = tmp;
|
|
|
- current = next;
|
|
|
- }
|
|
|
-
|
|
|
- shaderGraph.checkParameterIndex();
|
|
|
-
|
|
|
- for (id in shaderGraph.parametersKeys) {
|
|
|
- var elt = parametersList.find("#param_" + id);
|
|
|
- parametersList.append(elt);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
public function loadSettings() {
|
|
|
var save = haxe.Json.parse(getDisplayState("previewSettings") ?? "{}");
|
|
@@ -1227,14 +1138,12 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
|
|
|
}
|
|
|
|
|
|
public function revealParameter(id: Int) : Void {
|
|
|
- var param = parametersList.find("#param_" + id);
|
|
|
- parametersList.children().not(param).each((_, elt) -> toggleParameter(new JQuery(elt), false));
|
|
|
- toggleParameter(param, true);
|
|
|
- param.get(0).onanimationend = (e) -> {
|
|
|
- param.removeClass("reveal");
|
|
|
- };
|
|
|
- param.removeClass("reveal");
|
|
|
- param.addClass("reveal");
|
|
|
+ var param = shaderGraph.parametersAvailable[id];
|
|
|
+ parametersList.reveal(param.index);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function revealVariable(id: Int) : Void {
|
|
|
+ variableList.reveal(id);
|
|
|
}
|
|
|
|
|
|
public function disposeMeshPreview() {
|