// Load layers virtual protected void loadLayers(XElement data) { _layers = new List <MaterialLayer>(); foreach (XElement layerXml in data.Elements("Layer")) { _layers.Add(MaterialLayer.load(layerXml)); } }
// Load public static MaterialLayer load(XElement data) { MaterialLayer layer = null; switch (data.Attribute("type").Value) { case "root": layer = new MaterialGroupLayer(data); break; case "group": layer = new MaterialGroupLayer(data); break; case "texture": layer = new MaterialTextureLayer(data); break; case "perlin": layer = new MaterialPerlinLayer(data); break; case "worley": layer = new MaterialWorleyLayer(data); break; case "uniform_scatter": layer = new MaterialUniformScatterLayer(data); break; case "radial_scatter": layer = new MaterialRadialScatterLayer(data); break; case "edge_scatter": layer = new MaterialEdgeScatterLayer(data); break; case "leaves": layer = new MaterialLeavesLayer(data); break; } System.Diagnostics.Debug.Assert(layer != null, "Layer wasn't created (is null)"); return(layer); }
// Create public static MaterialLayer create(string type) { MaterialLayer layer = null; switch (type) { case "group": layer = new MaterialGroupLayer("group", true); break; case "texture": layer = new MaterialTextureLayer(); break; case "perlin": layer = new MaterialPerlinLayer(); break; case "worley": layer = new MaterialWorleyLayer(); break; case "uniform_scatter": layer = new MaterialUniformScatterLayer(); break; case "radial_scatter": layer = new MaterialRadialScatterLayer(); break; case "edge_scatter": layer = new MaterialEdgeScatterLayer(); break; case "leaves": layer = new MaterialLeavesLayer(); break; } System.Diagnostics.Debug.Assert(layer != null, "Layer wasn't created (is null)"); return(layer); }
// recursiveRenderLayers private Texture2D recursiveRenderLayers(Texture2D current, List<Vector2> polygonPoints, float growthFactor, MaterialLayer layer) { // Stop rendering at disabled layers if (!layer.enabled) return current; switch (layer.type) { case "root": // Render child layers without doing anything else MaterialGroupLayer rootLayer = layer as MaterialGroupLayer; foreach (MaterialLayer childLayer in rootLayer.layers) current = recursiveRenderLayers(current, polygonPoints, growthFactor, childLayer); current = texturePass(current, current, LayerBlendType.Opaque, 1f, rootLayer.multiplier, rootLayer.baseColor); break; case "group": // Render child layers, and do a texture pass at the end MaterialGroupLayer groupLayer = layer as MaterialGroupLayer; Texture2D groupCanvas = createCanvas(current.Width, current.Height); foreach (MaterialLayer childLayer in groupLayer.layers) groupCanvas = recursiveRenderLayers(groupCanvas, polygonPoints, growthFactor, childLayer); current = texturePass(current, groupCanvas, groupLayer.blendType, 1f, groupLayer.multiplier, groupLayer.baseColor); break; case "texture": MaterialTextureLayer textureLayer = layer as MaterialTextureLayer; current = texturePass( current, ResourceManager.getTexture(textureLayer.textureUID), textureLayer.blendType, textureLayer.scale, textureLayer.multiplier, textureLayer.baseColor); break; case "perlin": MaterialPerlinLayer perlinLayer = layer as MaterialPerlinLayer; Texture2D perlinTemporary = perlinPass( current, perlinLayer.seed, perlinLayer.position, perlinLayer.scale, perlinLayer.frequency, perlinLayer.gain, perlinLayer.lacunarity, perlinLayer.multiplier, perlinLayer.fbmOffset, perlinLayer.colorLow, perlinLayer.colorHigh, perlinLayer.iterations, perlinLayer.invert); // TODO: Move this code inside perlinPass? if (perlinLayer.blendType == LayerBlendType.Overlay) current = texturePass(current, perlinTemporary, LayerBlendType.Overlay, 1f, 1f, Color.White); else if (perlinLayer.blendType == LayerBlendType.Additive) current = texturePass(current, perlinTemporary, LayerBlendType.Additive, 1f, 1f, Color.White); else current = perlinTemporary; break; case "worley": MaterialWorleyLayer worleyLayer = layer as MaterialWorleyLayer; Texture2D worleyTemporary = worleyPass( current, worleyLayer.seed, worleyLayer.position, worleyLayer.scale, worleyLayer.frequency, worleyLayer.gain, worleyLayer.lacunarity, worleyLayer.multiplier, worleyLayer.fbmOffset, worleyLayer.colorLow, worleyLayer.colorHigh, worleyLayer.iterations, worleyLayer.worleyFeature, worleyLayer.invert); // TODO: Move this code inside worleyPass? if (worleyLayer.blendType == LayerBlendType.Overlay) current = texturePass(current, worleyTemporary, LayerBlendType.Overlay, 1f, 1f, Color.White); else if (worleyLayer.blendType == LayerBlendType.Additive) current = texturePass(current, worleyTemporary, LayerBlendType.Additive, 1f, 1f, Color.White); else current = worleyTemporary; break; case "uniform_scatter": MaterialUniformScatterLayer uniformLayer = layer as MaterialUniformScatterLayer; current = uniformScatterPass( current, uniformLayer.textureUIDs, uniformLayer.horizontalSpacing, uniformLayer.verticalSpacing, uniformLayer.jitter, uniformLayer.baseColor, uniformLayer.randomRed, uniformLayer.randomGreen, uniformLayer.randomBlue, uniformLayer.randomAlpha); break; case "radial_scatter": MaterialRadialScatterLayer radialLayer = layer as MaterialRadialScatterLayer; current = radialScatterPass( current, growthFactor, radialLayer.textureUIDs, radialLayer.scaleWithGrowthFactor, radialLayer.a, radialLayer.b, radialLayer.intersections, radialLayer.maxRadius, radialLayer.arms, radialLayer.twinArms, radialLayer.flipArms, radialLayer.useAbsoluteTextureAngle, radialLayer.absoluteTextureAngle, radialLayer.relativeTextureAngle, radialLayer.textureAngleJitter, radialLayer.jitter, radialLayer.centerJitter, radialLayer.centerOffset, radialLayer.baseColor, radialLayer.minTextureSize, radialLayer.maxTextureSize, radialLayer.randomRed, radialLayer.randomGreen, radialLayer.randomBlue, radialLayer.randomAlpha); break; case "edge_scatter": MaterialEdgeScatterLayer edgeLayer = layer as MaterialEdgeScatterLayer; current = edgeScatterPass( current, polygonPoints, edgeLayer.textureUIDs, edgeLayer.direction, edgeLayer.threshold, edgeLayer.hardCutoff, edgeLayer.spacing, edgeLayer.useAbsoluteAngle, edgeLayer.absoluteAngle, edgeLayer.relativeAngle, edgeLayer.angleJitter, edgeLayer.jitter, edgeLayer.scale, edgeLayer.scaleJitter, edgeLayer.baseColor, edgeLayer.randomRed, edgeLayer.randomGreen, edgeLayer.randomBlue, edgeLayer.randomAlpha); break; case "leaves": MaterialLeavesLayer leavesLayer = layer as MaterialLeavesLayer; current = leavesPass(current, growthFactor, leavesLayer.textureUIDs, leavesLayer.baseColor); break; } return current; }
// Select layer public void selectLayer(MaterialLayer layer) { Debug.Assert(layersTreeView.Nodes[0] is LayerNode); LayerNode targetNode = recursiveGetNode(layersTreeView.Nodes[0] as LayerNode, layer); layersTreeView.SelectedNode = targetNode; }
// recursiveGetNode private LayerNode recursiveGetNode(LayerNode startNode, MaterialLayer layer) { // Check this node's layer if (startNode.layer == layer) return startNode; if (startNode.layer.type == "root" || startNode.layer.type == "group") { // Spawn more searches, checking results foreach (TreeNode node in startNode.Nodes) { LayerNode result = recursiveGetNode(node as LayerNode, layer); if (result != null && result.layer == layer) return result; } } return null; }
// recursiveBuildNode private LayerNode recursiveBuildNode(MaterialLayer layer) { LayerNode node = new LayerNode(layer, layer.enabled); if (layer.type == "root" || layer.type == "group") { MaterialGroupLayer groupLayer = layer as MaterialGroupLayer; foreach (MaterialLayer childLayer in groupLayer.layers) node.Nodes.Add(recursiveBuildNode(childLayer)); } return node; }
// Add layer private void addNewLayer(MaterialLayer newLayer) { Debug.Assert(selectedLayer != null); LayerNode selectedNode = layersTreeView.SelectedNode as LayerNode; if (selectedLayer.type == "root" || selectedLayer.type == "group") { // Insert into group _controller.addTerrainLayer(selectedLayer as MaterialGroupLayer, newLayer, selectedNode.Nodes.Count); } else { // Create new layer LayerNode parent = selectedNode.Parent as LayerNode; // Add new layer to parent _controller.addTerrainLayer(parent.layer as MaterialGroupLayer, newLayer, selectedNode.Index + 1); } // Refresh tree populateTreeView(selectedMaterial.rootLayer); // Select layer selectLayer(newLayer); // Refocus on tree layersTreeView.Focus(); // Set changes made _controller.setChangesMade(true); }
// Load root layer virtual protected void loadRootLayer(XElement data) { _rootLayer = MaterialLayer.load(data.Element("Layer")) as MaterialGroupLayer; }