// 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); }
// 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; }
public LayerNode(MaterialLayer layer, bool enabled) : base() { _layer = layer; Text = _layer.ToString(); Checked = enabled; }
public void Material2LayerTest() { var input = new MaterialLayer { Id = 1234, IsLinear = false, IsMipmap = true, Parts = new [] { new MaterialLayer.Part { Name = "mlink", Properties = new object[] { "gfx/someres", 1, 2, 3 } }, new MaterialLayer.Part { Name = "col", Properties = new object[] { 1, 2.0f, "dsd", new Point2D(1, 2) } }, new MaterialLayer.Part { Name = "mipmap", Properties = new object[0] }, } }; var serializer = new Material2LayerHandler(); var output = (MaterialLayer)serializer.Reserialize(input); Assert.That(output.Id, Is.EqualTo(input.Id)); Assert.That(output.IsLinear, Is.EqualTo(input.IsLinear)); Assert.That(output.IsMipmap, Is.EqualTo(input.IsMipmap)); Assert.That(output.Parts, Is.Not.Null); Assert.That(output.Parts.Length, Is.EqualTo(input.Parts.Length)); foreach (var inputMaterial in input.Parts) { var outputMaterial = output.Parts.FirstOrDefault(x => x.Name == inputMaterial.Name); Assert.That(outputMaterial, Is.Not.Null); Assert.That(outputMaterial.Properties, Is.EquivalentTo(inputMaterial.Properties)); } }
/// <summary> /// This method will be called when the RenderTarget and views are created. /// Here you must create the scene, cameras and all the elements that you need /// </summary> private void OnInitializeRender() { // To render sprites, we do not need the depth renderView.State.DepthEnabled = false; // A new Scene!! scene = new Scene(); camera = new OrthoCamera(new StringBuilder("camera")); renderView.State.CullMode = CULLMODE_STATE.NONE; // Each scene is composed of nodes scene.Root.AddChildren(node = new Node()); // We need a material for this sprite Material material = new Material("standard"); MaterialLayer layer = material.CreateLayer(); layer.DiffuseMap = editorEngine.Textures.CreateTexture2DFromFile(new StringBuilder("stone")); // Creates a new sprite sp = editorEngine.Sprites.Create(100, 100); sp.Material = material; // Add the sprite to the node node.AddRenderable(sp); }
// Add layer button clicked private void addLayerButton_Click(object sender, EventArgs e) { Debug.Assert(layersTreeView.SelectedNode is LayerNode); SelectMaterialLayerType newLayerForm = new SelectMaterialLayerType(); if (newLayerForm.ShowDialog() == DialogResult.OK) { LayerNode node = layersTreeView.SelectedNode as LayerNode; MaterialLayer newLayer = EditorMaterialLayer.create(newLayerForm.getSelectedType()); addNewLayer(newLayer); } }
// moveTerrainLayerDown public void moveTerrainLayerDown(MaterialGroupLayer parent, MaterialLayer layer) { Debug.Assert(parent.layers.Contains(layer)); // Store current layer index int index = parent.layers.IndexOf(layer); // Remove layer from parent list parent.layers.Remove(layer); // Insert at the position after its last position parent.layers.Insert(index + 1, layer); }
// 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); }
static MaterialLayer Deserialize(string data, object[] args) { var materialLayer = new MaterialLayer(); // custom callback for ShaderProperty Func <object, string, object> onDeserializeShaderProperty = (spObj, spData) => { if (spData == "__NULL__") { return(null); } // HACK figure out which property is being deserialized based on name // substring(11) will strip: sp(name:" ShaderProperty targetProperty = materialLayer.sourceShaderProperty; if (spData.Substring(9).StartsWith("contrast_")) { // Can't deserialize to null, so we need to create the Shader Property first materialLayer.contrastProperty = new ShaderProperty("temp_contrast", ShaderProperty.VariableType.@float); targetProperty = materialLayer.contrastProperty; } if (spData.Substring(9).StartsWith("noise_")) { // Can't deserialize to null, so we need to create the Shader Property first materialLayer.noiseProperty = new ShaderProperty("temp_noise", ShaderProperty.VariableType.@float); targetProperty = materialLayer.noiseProperty; } if (targetProperty == null) { return(null); } // custom callback for Implementations Func <object, string, object> onDeserializeImplementation = (impObj, impData) => { return(ShaderGenerator2.CurrentConfig.DeserializeImplementationHandler(impObj, impData, targetProperty)); }; var implementationHandling = new Dictionary <Type, Func <object, string, object> > { { typeof(ShaderProperty.Implementation), onDeserializeImplementation } }; return(Serialization.DeserializeTo(targetProperty, spData, typeof(ShaderProperty), null, implementationHandling)); }; var shaderPropertyHandling = new Dictionary <Type, Func <object, string, object> > { { typeof(ShaderProperty), onDeserializeShaderProperty } }; return((MaterialLayer)Serialization.DeserializeTo(materialLayer, data, typeof(MaterialLayer), null, shaderPropertyHandling)); }
void AddSphere() { scene.Root.AddChildren(node = new Node(new StringBuilder("Sphere"))); sphereMesh = new RenderableMesh(editorEngine, GeometryFactory.CreateSphere(editorEngine, 3, 5)); node.AddRenderable(sphereMesh); Material material = new Material("earth"); MaterialLayer layer = material.CreateLayer(); layer.DiffuseMap = editorEngine.Textures.CreateTexture2DFromFile(new StringBuilder("earth")); sphereMesh.Material = material; }
/// <summary> /// Returns whether or not the setting is overridden by the active layer /// </summary> public bool SettingExistsInLayer(string sliceSetting, NamedSettingsLayers layer) { switch (layer) { case NamedSettingsLayers.Quality: return(QualityLayer?.ContainsKey(sliceSetting) == true); case NamedSettingsLayers.Material: return(MaterialLayer?.ContainsKey(sliceSetting) == true); case NamedSettingsLayers.User: return(UserLayer?.ContainsKey(sliceSetting) == true); default: return(false); } }
void AddCube() { scene.Root.AddChildren(node = new Node(new StringBuilder("Cube"))); // A cube with six faces, each one with its own material cubeMesh = GeometryFactory.CreateCube(editorEngine); for (int numFace = 0; numFace < 6; numFace++) { Material material = new Material("standard"); MaterialLayer layer = material.CreateLayer(); layer.ShaderID = 0; layer.DiffuseMap = editorEngine.Textures.CreateTexture2DFromFile(new StringBuilder((numFace + 1).ToString())); if (numFace == 0) { layer.NormalMap = editorEngine.Textures.CreateTexture2DFromFile(new StringBuilder("bump_NM_height")); } cubeMesh.Materials.Add(material); } node.ScaleX = 30; node.ScaleZ = 30; node.ScaleY = 0.01f; //mesh.Visible = false; node.AddRenderable(cubeMesh); // A new node scene.Root.AddChildren(node2 = new Node(new StringBuilder("clone"))); node2.Position = new AIOEngine.MathSpace.Vector3(2, 1, 0); RenderableMeshMultiMaterial mesh2 = cubeMesh.Clone(); //node2.AddRenderable(mesh2); mesh2.Visible = false; mesh2.DrawBounding = true; }
// 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); }
public void RefreshLookupTable() { bool is_dirty = m_layer_idx_to_material == null; int max_layer_idx = 0; for (int i = 0; i < m_material_entries.Length; ++i) { var entry = m_material_entries[i]; var material = entry.m_material; var new_layer_idx = material.GetInt(LAYER_IDX_ID); var new_hue_variation_amount = material.GetFloat(HUE_VARIATION_AMOUNT_ID); var new_saturation_variation_amount = material.GetFloat(SATURATION_VARIATION_AMOUNT_ID); var new_bottom_color = material.GetColor(BOTTOM_COLOR_ID); var new_top_color = material.GetColor(TOP_COLOR_ID); var new_noise_opacity = material.GetFloat(NOISE_OPACITY_ID); var new_noise_tiling = material.GetFloat(NOISE_TILING_ID); max_layer_idx = Math.Max(max_layer_idx, new_layer_idx); bool is_layer_idx_dirty = entry.m_layer_idx != new_layer_idx; bool is_hue_variation_amount_dirty = new_hue_variation_amount != entry.m_hue_variation_amount; bool is_saturation_variation_amount_dirty = new_saturation_variation_amount != entry.m_saturation_variation_amount; bool is_bottom_color_dirty = new_bottom_color != entry.m_bottom_color; bool is_top_color_dirty = new_top_color != entry.m_top_color; bool is_noise_opacity_dirty = new_noise_opacity != entry.m_noise_opacity; bool is_noise_tiling_dirty = new_noise_tiling != entry.m_noise_tiling; bool are_parameters_dirty = is_layer_idx_dirty || is_hue_variation_amount_dirty || is_saturation_variation_amount_dirty || is_bottom_color_dirty || is_top_color_dirty || is_noise_opacity_dirty || is_noise_tiling_dirty; if (!are_parameters_dirty) { continue; } is_dirty = true; entry.m_layer_idx = new_layer_idx; entry.m_hue_variation_amount = new_hue_variation_amount; entry.m_saturation_variation_amount = new_saturation_variation_amount; entry.m_bottom_color = new_bottom_color; entry.m_top_color = new_top_color; entry.m_noise_opacity = new_noise_opacity; entry.m_noise_tiling = new_noise_tiling; m_material_entries[i] = entry; } if (is_dirty) { Array.Sort(m_material_entries, (x, y) => x.m_layer_idx - y.m_layer_idx); m_layer_idx_to_material = new MaterialLayer[max_layer_idx + 1]; int last_layer_idx = 0; int layer_idx = 0; foreach (var entry in m_material_entries) { float blend_range = Mathf.Max((float)entry.m_layer_idx - (float)last_layer_idx, 1f); for (; layer_idx <= entry.m_layer_idx; ++layer_idx) { float color_blend_factor = (layer_idx - last_layer_idx) / blend_range; var property_block = new MaterialPropertyBlock(); var computed_color = Color.Lerp(entry.m_bottom_color, entry.m_top_color, color_blend_factor); Color.RGBToHSV(computed_color, out var hue, out var saturation, out var value); if (entry.m_hue_variation_amount > 0) { float hue_variation = HUE_VARIATION_PATTERN[layer_idx % HUE_VARIATION_PATTERN.Length]; hue += hue_variation * entry.m_hue_variation_amount; } if (entry.m_saturation_variation_amount > 0) { float saturation_variation = SATURATION_VARIATION_PATTERN[layer_idx % SATURATION_VARIATION_PATTERN.Length]; saturation += saturation_variation * entry.m_saturation_variation_amount; } computed_color = Color.HSVToRGB(hue, saturation, value); var material = GameObject.Instantiate(entry.m_material); material.SetColor(COMPUTED_COLOR_ID, computed_color); material.SetFloat(NOISE_OPACITY_ID, entry.m_noise_opacity); material.SetFloat(NOISE_TILING_ID, entry.m_noise_tiling); var tri_planar_offset = new Vector3(layer_idx * 3, layer_idx * 7, layer_idx * 11); material.SetVector(TRI_PLANAR_OFFSET_ID, tri_planar_offset); m_layer_idx_to_material[layer_idx] = new MaterialLayer { m_material = material, }; } last_layer_idx = entry.m_layer_idx; } } }
// removeTerrainLayer public void removeTerrainLayer(MaterialGroupLayer parent, MaterialLayer layer) { parent.layers.Remove(layer); }
// addTerrainLayer public void addTerrainLayer(MaterialGroupLayer parent, MaterialLayer layer, int index) { parent.layers.Insert(index, 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); }