List <BiomeSwitchData> GetPrecedentSwitchDatas(PWNode currentNode, PWNode rootNode) { var precedentSwitchDatas = new List <BiomeSwitchData>(); PWNode n = currentNode; while (n != rootNode) { PWNode prevNode = n; n = n.GetInputNodes().First(); if (n.GetType() != typeof(PWNodeBiomeSwitch)) { break; } var switches = (n as PWNodeBiomeSwitch).switchList; int index = n.outputAnchors.ToList().FindIndex(a => a.links.Any(l => l.toNode == prevNode)); if (index == -1) { throw new Exception("[PWBiomeSwitchGraph] IMPOSSIBRU !!!!! check your node API !"); } precedentSwitchDatas.Add(switches[index]); } precedentSwitchDatas.Reverse(); return(precedentSwitchDatas); }
public virtual void OnEnable() { //check if the object have been initialized, if not, quit. if (!initialized) { return; } //Events attach OnPostLinkCreated += LinkPostAddedCallback; OnPostLinkRemoved += LinkPostRemovedCallback; OnNodeRemoved += NodeCountChangedCallback; OnNodeAdded += NodeCountChangedCallback; OnAllNodeReady += NodeReadyCallback; graphProcessor.OnEnable(); //get the in and out node arrays refelection getters: inputNodeOutputValues = inputNode.GetType().GetField("outputValues", BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance); outputNodeInputValues = outputNode.GetType().GetField("inputValues", BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance); //Send OnAfterSerialize here because when graph's OnEnable function is // called, all it's nodes are already deserialized. foreach (var node in nodes) { if (node != null) { node.OnAfterGraphDeserialize(this); } } }
public string FindGraphNameFromExternalNode(PWNode node) { if (node.GetType() != typeof(PWNodeGraphExternal)) { return(null); } return(subgraphReferences.FirstOrDefault(gName => { var g = FindGraphByName(gName); if (g.externalGraphNode.nodeId == node.nodeId) { return true; } return false; })); }
static void CreateNode(PWGraph graph, PWGraphCommand command, string inputCommand) { Vector2 position = command.position; PWNode node = null; //if we receive a CreateNode with input/output graph nodes, we assign them so we don't have multiple inout/output nodes if (command.nodeType == typeof(PWNodeGraphInput) || command.nodeType == typeof(PWNodeBiomeGraphInput)) { node = graph.inputNode; } else if (command.nodeType == typeof(PWNodeGraphOutput) || command.nodeType == typeof(PWNodeBiomeGraphOutput)) { node = graph.outputNode; } else { node = graph.CreateNewNode(command.nodeType, position); } //set the position again for input/output nodes node.rect.position = position; Type nodeType = node.GetType(); if (!String.IsNullOrEmpty(command.attributes)) { foreach (var attr in PWJson.Parse(command.attributes)) { FieldInfo attrField = nodeType.GetField(attr.first, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); if (attrField != null) { attrField.SetValue(node, attr.second); } else { Debug.LogError("Attribute " + attr.first + " can be found in node " + node); } } } node.name = command.name; }
void BuildTreeInternal(PWNode node, BiomeSwitchNode currentNode, int depth, BiomeSwitchNode parent = null) { if (node == null) { return; } //TODO: anchor to multiple PWNodeBiomeSwitch management if (node.GetType() == typeof(PWNodeBiomeSwitch)) { PWNodeBiomeSwitch bSwitch = node as PWNodeBiomeSwitch; int outputLinksCount = bSwitch.GetLinks().Count; int childIndex = 0; List <PWNode> outputNodeList = new List <PWNode>(); Debug.Log("encountered switch: " + bSwitch.switchMode); currentNode.SetChildCount(outputLinksCount); switch (bSwitch.switchMode) { case BiomeSwitchMode.Water: int?terrestrialAnchorId = node.GetAnchorId(PWAnchorType.Output, 0); int?aquaticAnchorId = node.GetAnchorId(PWAnchorType.Output, 1); if (terrestrialAnchorId != null) { var nodes = node.GetNodesAttachedToAnchor(terrestrialAnchorId.Value); outputNodeList.AddRange(nodes); // Debug.Log("terrestrialNodes: " + nodes[0].nodeId); for (int i = 0; i < nodes.Count; i++) { currentNode.GetChildAt(childIndex++).SetSwitchValue(false, bSwitch.switchMode, "terrestrial", Color.black); } biomeCoverage[BiomeSwitchMode.Water] += 0.5f; } //get all nodes on the first anchor: if (aquaticAnchorId != null) { var nodes = node.GetNodesAttachedToAnchor(aquaticAnchorId.Value); // Debug.Log("aquaticNodes: " + nodes[0].nodeId); outputNodeList.AddRange(nodes); for (int i = 0; i < nodes.Count; i++) { currentNode.GetChildAt(childIndex++).SetSwitchValue(true, bSwitch.switchMode, "aquatic", Color.blue); } biomeCoverage[BiomeSwitchMode.Water] += 0.5f; } break; default: // Debug.Log("swicth data count for node " + node.nodeId + ": " + bSwitch.switchDatas.Count); for (int anchorIndex = 0; anchorIndex < bSwitch.switchDatas.Count; anchorIndex++) { int?anchorId = node.GetAnchorId(PWAnchorType.Output, anchorIndex); var sData = bSwitch.switchDatas[anchorIndex]; if (anchorId == null) { continue; } var attachedNodesToAnchor = node.GetNodesAttachedToAnchor(anchorId.Value); outputNodeList.AddRange(attachedNodesToAnchor); // if (attachedNodesToAnchor.Count == 0) // Debug.LogWarning("nothing attached to the biome switch output " + anchorIndex); foreach (var attachedNode in attachedNodesToAnchor) { var child = currentNode.GetChildAt(childIndex++); child.SetSwitchValue(sData.min, sData.max, bSwitch.switchMode, sData.name, sData.color); } biomeCoverage[bSwitch.switchMode] += (sData.max - sData.min) / (sData.absoluteMax - sData.absoluteMin); } break; } childIndex = 0; foreach (var outNode in outputNodeList) { if (bSwitch.switchMode == BiomeSwitchMode.Water) { Debug.Log("water switch mode output type: " + currentNode.GetChildAt(childIndex) + " [" + childIndex + "] -> " + outNode); } BuildTreeInternal(outNode, currentNode.GetChildAt(childIndex, true), depth + 1, currentNode); Type outNodeType = outNode.GetType(); if (outNodeType == typeof(PWNodeBiomeSwitch) || outNodeType == typeof(PWNodeBiomeBinder)) { childIndex++; } } } else if (node.GetType() == typeof(PWNodeBiomeBinder)) { PWNodeBiomeBinder binder = node as PWNodeBiomeBinder; string biomeName = currentNode.biomeName; if (String.IsNullOrEmpty(biomeName)) { Debug.LogWarning("Biome name null or empty for biomeBinder: " + binder); return; } //Biome binder detected, assign the biome to the current Node: currentNode.biome = binder.outputBiome; // Debug.Log("current node: " + currentNode + ", preview color: " + currentNode.previewColor); //set the color of the biome in the binder binder.outputBiome.previewColor = currentNode.previewColor; Debug.Log("set biome " + currentNode.biome + " in node " + currentNode); //set the biome ID and name: currentNode.biome.name = biomeName; currentNode.biome.id = biomeIdCount++; //store the biome in dictionaries for fast access biomePerId[currentNode.biome.id] = currentNode.biome; biomePerName[biomeName] = currentNode.biome; } else { foreach (var outNode in node.GetOutputNodes()) { BuildTreeInternal(outNode, currentNode, depth++, parent); } } return; }
void UpdateRelativeBounds() { var inputNodes = GetInputNodes(); if (inputNodes.Count() == 0) { return; } PWNode prevNode = inputNodes.First(); PWNode currentNode = this; while (prevNode.GetType() == typeof(PWNodeBiomeSwitch)) { PWNodeBiomeSwitch prevSwitch = (PWNodeBiomeSwitch)prevNode; if (prevSwitch.samplerName != samplerName) { inputNodes = prevNode.GetInputNodes(); if (inputNodes.Count() == 0) { return; } currentNode = prevNode; prevNode = inputNodes.First(); continue; } var prevNodeOutputAnchors = prevSwitch.outputAnchors.ToList(); for (int i = 0; i < prevNodeOutputAnchors.Count; i++) { var anchor = prevNodeOutputAnchors[i]; if (anchor.links.Any(l => l.toNode == currentNode)) { relativeMin = prevSwitch.switchList.switchDatas[i].min; relativeMax = prevSwitch.switchList.switchDatas[i].max; } } break; } if (prevNode.GetType() != typeof(PWNodeBiomeSwitch)) { //update currentSampler value: if (inputBiome != null) { currentSampler = inputBiome.GetSampler(samplerName); } if (currentSampler == null) { return; } relativeMin = currentSampler.min; relativeMax = currentSampler.max; return; } }
public bool BuildGraph(BiomeData biomeData) { ResetGraph(); PWNode rootNode = biomeData.biomeSwitchGraphStartPoint; Stack <PWNode> biomeNodes = new Stack <PWNode>(); biomeNodes.Push(rootNode); BiomeSwitchCell currentCell = null; //fill param range dictionary (used to compute weights) FillParamRange(biomeData); while (biomeNodes.Count > 0) { PWNode currentNode = biomeNodes.Pop(); Type nodeType = currentNode.GetType(); if (nodeType == typeof(PWNodeBiome)) { //get all precedent switch data in the order of the tree (start from rootNode) var precedentSwitchDatas = GetPrecedentSwitchDatas(currentNode, rootNode); var biomeNode = currentNode as PWNodeBiome; var lastSwitch = precedentSwitchDatas.Last(); currentCell = new BiomeSwitchCell(); //Set cell and partial biome remaining empty params currentCell.name = biomeNode.outputBiome.name = lastSwitch.name; currentCell.id = biomeNode.outputBiome.id = biomeIdCount++; currentCell.color = biomeNode.outputBiome.previewColor = lastSwitch.color; currentCell.weight = currentCell.GetWeight(paramRanges); //add the partial biome to utility dictionary accessors: partialBiomePerName[currentCell.name] = biomeNode.outputBiome; partialBiomePerId[currentCell.id] = biomeNode.outputBiome; //load all access condition for this biome switch foreach (var sd in precedentSwitchDatas) { int index = biomeData.GetBiomeIndex(sd.samplerName); var param = currentCell.switchParams.switchParams[index]; param.enabled = true; param.min = sd.min; param.max = sd.max; biomeCoverage[index] += (sd.max - sd.min) / (sd.absoluteMax - sd.absoluteMin); } } else if (nodeType == typeof(PWNodeBiomeBlender)) { if (currentCell == null) { throw new Exception("[PWBiomeSwitchGraph] idk what happened but this is really bad"); } //if the flow reaches the biomeblender everything is OK and add the current cell to the graph cells.Add(currentCell); continue; } foreach (var outputNode in currentNode.GetOutputNodes()) { biomeNodes.Push(outputNode); } } //Generate links between all linkable nodes BuildLinks(); rootCell = cells.First(); if (!CheckValid()) { return(false); } isBuilt = true; return(true); }
void ProcessNodeLinks(PWNode node) { var links = node.GetLinks(); foreach (var link in links) { if (!nodesDictionary.ContainsKey(link.distantNodeId)) { continue; } if (link.mode == PWNodeProcessMode.RequestForProcess) { continue; } var target = nodesDictionary[link.distantNodeId]; if (target == null) { continue; } // Debug.Log("local: " + link.localClassAQName + " / " + node.GetType() + " / " + node.nodeId); // Debug.Log("distant: " + link.distantClassAQName + " / " + target.GetType() + " / " + target.nodeId); //ignore old links not removed cause of property removed in a script at compilation if (!realMode) { if (!bakedNodeFields.ContainsKey(link.localClassAQName) || !bakedNodeFields[link.localClassAQName].ContainsKey(link.localName) || !bakedNodeFields[link.distantClassAQName].ContainsKey(link.distantName)) { Debug.LogError("Can't find field: " + link.localName + " in " + link.localClassAQName + " OR " + link.distantName + " in " + link.distantClassAQName); continue; } } var val = bakedNodeFields[link.localClassAQName][link.localName].GetValue(node); if (val == null) { Debug.Log("null value of node: " + node.GetType() + " of field: " + link.localName); } var prop = bakedNodeFields[link.distantClassAQName][link.distantName]; // Debug.Log("set value: " + val.GetHashCode() + "(" + val + ")" + " to " + target.GetHashCode() + "(" + target + ")"); // simple assignation, without multi-anchor if (link.distantIndex == -1 && link.localIndex == -1) { if (realMode) { prop.SetValue(target, val); } else { try { prop.SetValue(target, val); } catch (Exception e) { Debug.LogError(e); } } } else if (link.distantIndex != -1 && link.localIndex == -1) //distant link is a multi-anchor { PWValues values = (PWValues)prop.GetValue(target); if (values != null) { if (!values.AssignAt(link.distantIndex, val, link.localName)) { Debug.Log("failed to set distant indexed field value: " + link.distantName); } } } else if (link.distantIndex == -1 && link.localIndex != -1 && val != null) //local link is a multi-anchor { object localVal = ((PWValues)val).At(link.localIndex); if (realMode) { prop.SetValue(target, localVal); } else { try { prop.SetValue(target, localVal); } catch { Debug.LogWarning("can't assign " + link.localName + " to " + link.distantName); } } } else if (val != null) // both are multi-anchors { PWValues values = (PWValues)prop.GetValue(target); object localVal = ((PWValues)val).At(link.localIndex); if (values != null) { // Debug.Log("assigned total multi"); if (!values.AssignAt(link.distantIndex, localVal, link.localName)) { Debug.Log("failed to set distant indexed field value: " + link.distantName); } } } } }
public PWNodeProcessInfo(PWNode n, string g) { node = n; graphName = g; type = n.GetType(); }