/// <summary> /// Create a node and add it to the view-model. /// </summary> public NodeViewModel CreateNode(ModuleBase moduleBase, Point nodeLocation, bool centerNode) { System.Windows.Media.Brush generatorBrush = new LinearGradientBrush(Colors.White, Colors.Orange, 90.0); System.Windows.Media.Brush operatorBrush = new LinearGradientBrush(Colors.White, Colors.PowderBlue, 90.0); System.Windows.Media.Brush finalBrush = new LinearGradientBrush(Colors.White, Colors.YellowGreen, 90.0); NodeViewModel node = new NodeViewModel(new LibnoiseNode(moduleBase)); node.Module.ID = moduleBase.GetType().Name + "_" + (Network.Nodes.Count(n => n.Module.ModuleType.Equals(moduleBase.GetType().Name)) + 1); node.X = nodeLocation.X; node.Y = nodeLocation.Y; node.StrokeBrush = System.Windows.Media.Brushes.Black; // this can be simplified, for sure, but I left in the giant ugly switch // in the event I want to do something unique by type, such as any additional // colouring or whatever. It's a little gross to look at, but it does the job switch (moduleBase.GetType().Name) { // Generators should not have any input values case "Billow": node.FillBrush = generatorBrush; break; case "Checker": node.FillBrush = generatorBrush; break; case "Const": node.FillBrush = generatorBrush; break; case "Cylinders": node.FillBrush = generatorBrush; break; case "Perlin": node.FillBrush = generatorBrush; break; case "RidgedMultifractal": node.FillBrush = generatorBrush; break; case "Spheres": node.FillBrush = generatorBrush; break; case "Voronoi": node.FillBrush = generatorBrush; break; case "Abs": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "Add": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Left")); node.InputConnectors.Add(new ConnectorViewModel("Right")); break; case "Blend": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Left")); node.InputConnectors.Add(new ConnectorViewModel("Right")); node.InputConnectors.Add(new ConnectorViewModel("Operator")); break; case "Cache": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "Clamp": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "Curve": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "Displace": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Primary")); node.InputConnectors.Add(new ConnectorViewModel("X")); node.InputConnectors.Add(new ConnectorViewModel("Y")); node.InputConnectors.Add(new ConnectorViewModel("Z")); break; case "Exponent": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "Invert": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "Max": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Left")); node.InputConnectors.Add(new ConnectorViewModel("Right")); break; case "Min": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Left")); node.InputConnectors.Add(new ConnectorViewModel("Right")); break; case "Multiply": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Left")); node.InputConnectors.Add(new ConnectorViewModel("Right")); break; case "Power": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Left")); node.InputConnectors.Add(new ConnectorViewModel("Right")); break; case "Rotate": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "Scale": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "ScaleBias": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "Select": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Primary")); node.InputConnectors.Add(new ConnectorViewModel("Secondary")); node.InputConnectors.Add(new ConnectorViewModel("Controller")); break; case "Subtract": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Left")); node.InputConnectors.Add(new ConnectorViewModel("Right")); break; case "Terrace": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "Translate": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "Turbulence": node.FillBrush = operatorBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; case "Final": node.FillBrush = finalBrush; node.InputConnectors.Add(new ConnectorViewModel("Input")); break; default: break; } // for the 'Final' node, don't add any outputs. if (!moduleBase.GetType().Name.Equals("Final")) { node.OutputConnectors.Add(new ConnectorViewModel("Output")); } if (centerNode) { // // We want to center the node. // // For this to happen we need to wait until the UI has determined the // size based on the node's data-template. // // So we define an anonymous method to handle the SizeChanged event for a node. // // Note: If you don't declare sizeChangedEventHandler before initializing it you will get // an error when you try and unsubscribe the event from within the event handler. // EventHandler<EventArgs> sizeChangedEventHandler = null; sizeChangedEventHandler = delegate(object sender, EventArgs e) { // // This event handler will be called after the size of the node has been determined. // So we can now use the size of the node to modify its position. // node.X -= node.Size.Width / 2; node.Y -= node.Size.Height / 2; // // Don't forget to unhook the event, after the initial centering of the node // we don't need to be notified again of any size changes. // node.SizeChanged -= sizeChangedEventHandler; }; // // Now we hook the SizeChanged event so the anonymous method is called later // when the size of the node has actually been determined. // node.SizeChanged += sizeChangedEventHandler; } // // Add the node to the view-model. // this.Network.Nodes.Add(node); return node; }
// simple recursive call to cycle through a selected module // and their connected children and set the seed value to the // seed selected by the user. If a seed value already exists, // then leave it alone... or maybe add it together? private void SetSeeds(ModuleBase module, int seed) { switch (module.GetType().Name) { case "Billow": if (((Billow)module).Seed == 0) ((Billow)module).Seed = seed; break; case "Perlin": if (((Perlin)module).Seed == 0) ((Perlin)module).Seed = seed; break; case "RidgedMultifractal": if (((RidgedMultifractal)module).Seed == 0) ((RidgedMultifractal)module).Seed = seed; break; case "Voronoi": if (((Voronoi)module).Seed == 0) ((Voronoi)module).Seed = seed; break; case "Turbulence": if (((Turbulence)module).Seed == 0) ((Turbulence)module).Seed = seed; break; default: break; } if (module.Modules != null && module.Modules.Count() > 0) { foreach (ModuleBase mb in module.Modules) { SetSeeds(mb, seed); } } }