|
@@ -13,14 +13,15 @@ import java.util.List;
|
|
|
import org.openide.util.WeakListeners;
|
|
|
|
|
|
/**
|
|
|
- * A ShaderNodeBlock is a shader node in the MatDef file.
|
|
|
- *
|
|
|
+ * A ShaderNodesBlock is a set of shader nodes in the MatDef file, for example all frag shader nodes.
|
|
|
+ *
|
|
|
* @author Nehon
|
|
|
*/
|
|
|
public class ShaderNodesBlock extends UberStatement implements PropertyChangeListener {
|
|
|
-
|
|
|
+
|
|
|
protected ShaderNodesBlock(int lineNumber, String line) {
|
|
|
super(lineNumber, line);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
public ShaderNodesBlock(Statement sta) {
|
|
@@ -47,14 +48,20 @@ public class ShaderNodesBlock extends UberStatement implements PropertyChangeLis
|
|
|
|
|
|
@Override
|
|
|
public void propertyChange(PropertyChangeEvent evt) {
|
|
|
- if (evt.getPropertyName().equals("order")) {
|
|
|
+ if (evt.getPropertyName().equals(ShaderNodeBlock.ADD_MAPPING) || evt.getPropertyName().equals("order")) {
|
|
|
sort();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void sort() {
|
|
|
List<ShaderNodeBlock> list = getShaderNodes();
|
|
|
- Collections.sort(list, new NodeComparator());
|
|
|
+ int passes = 0;
|
|
|
+ NodeComparator nodeComparator = new NodeComparator(list);
|
|
|
+ while (nodeComparator.changes != 0 && passes < 10) {
|
|
|
+ nodeComparator.changes = 0;
|
|
|
+ Collections.sort(list, nodeComparator);
|
|
|
+ passes++;
|
|
|
+ }
|
|
|
contents.clear();
|
|
|
contents.addAll(list);
|
|
|
fire("reorder", null, null);
|
|
@@ -62,26 +69,58 @@ public class ShaderNodesBlock extends UberStatement implements PropertyChangeLis
|
|
|
|
|
|
/**
|
|
|
* Sorts nodes so that they are initialized after their input dependencies.
|
|
|
+ * Will look higher up in hierarchy and move node incrementally. This may require several passes
|
|
|
*/
|
|
|
- private class NodeComparator implements Comparator<ShaderNodeBlock> {
|
|
|
+ private final class NodeComparator implements Comparator<ShaderNodeBlock> {
|
|
|
+
|
|
|
+ private final List<ShaderNodeBlock> list;
|
|
|
+ private int changes = -1;
|
|
|
+
|
|
|
+ public NodeComparator(List<ShaderNodeBlock> list) {
|
|
|
+ this.list = list;
|
|
|
+ }
|
|
|
|
|
|
@Override
|
|
|
public int compare(ShaderNodeBlock o1, ShaderNodeBlock o2) {
|
|
|
if (o1.name.equals(o2.name)) {
|
|
|
return 0;
|
|
|
}
|
|
|
- for (String s : o1.inputNodes) {
|
|
|
- if (s.contains(o2.name)) {
|
|
|
- return 1;
|
|
|
- }
|
|
|
+ if (hasInputConnection(o2.name, o1)) {
|
|
|
+ changes++;
|
|
|
+ return 1;
|
|
|
}
|
|
|
- for (String s : o2.inputNodes) {
|
|
|
- if (s.contains(o1.name)) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
+ if (hasInputConnection(o1.name, o2)) {
|
|
|
+ changes++;
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((o1.globalInput && o2.globalOutput) || (o2.globalInput && o1.globalOutput)) {
|
|
|
+ changes++;
|
|
|
+ return (int) Math.signum(o1.spatialOrder - o2.spatialOrder);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+ private ShaderNodeBlock findAncestorNode(String name) {
|
|
|
+ for (ShaderNodeBlock node : list) {
|
|
|
+ if (node.name.equals(name)) {
|
|
|
+ return node;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean hasInputConnection(String name, ShaderNodeBlock node) {
|
|
|
+ for (String s : node.inputNodes) {
|
|
|
+ if (s.equals(name)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ ShaderNodeBlock ancestor = findAncestorNode(s);
|
|
|
+ if (ancestor != null && hasInputConnection(name, ancestor)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
}
|