/// <summary> /// Updates the surface graph asset (save new one, discard cached data, reload asset). /// </summary> /// <returns>True if cannot save it, otherwise false.</returns> public static bool SaveSurface(JsonAsset asset, RenderingGraph assetInstance, byte[] surfaceData) { if (!asset) { throw new ArgumentNullException(nameof(asset)); } assetInstance.VisjectSurface = surfaceData; return(FlaxEditor.Editor.SaveJsonAsset(asset.Path, assetInstance)); }
/// <summary> /// Tries to load surface graph from the asset. /// </summary> /// <param name="createDefaultIfMissing">True if create default surface if missing, otherwise won't load anything.</param> /// <returns>Loaded surface bytes or null if cannot load it or it's missing.</returns> public static byte[] LoadSurface(JsonAsset asset, RenderingGraph assetInstance, bool createDefaultIfMissing) { if (!asset) { throw new ArgumentNullException(nameof(asset)); } if (assetInstance == null) { throw new ArgumentNullException(nameof(assetInstance)); } // Return its data if (assetInstance.VisjectSurface?.Length > 0) { return(assetInstance.VisjectSurface); } // Create it if it's missing if (createDefaultIfMissing) { // A bit of a hack // Create a Visject Graph with a main node and serialize it! var surfaceContext = new VisjectSurfaceContext(null, null, new FakeSurfaceContext()); // Add the main node var node = NodeFactory.CreateNode(GetGroupArchetypes(), 1, surfaceContext, MainNodeGroupId, MainNodeTypeId); if (node == null) { Debug.LogWarning("Failed to create main node."); return(null); } surfaceContext.Nodes.Add(node); node.Location = Vector2.Zero; surfaceContext.Save(); return(surfaceContext.Context.SurfaceData); } else { return(null); } }
public void CompileSurface(RenderingGraph graph) { // We're mapping every output box to an index // So we can store the node outputs in an array var variableIndexGetter = new GraphVariables(); // Get the parameters GetParameterGetterNodeArchetype(out ushort paramNodeGroupId); var graphParams = new Dictionary <Guid, GraphParameter>(); var parameters = new GraphParameter[Parameters.Count]; for (int i = 0; i < Parameters.Count; i++) { var param = Parameters[i]; var graphParameter = new GraphParameter(param.Name, param.Value, variableIndexGetter.RegisterVariable()); graphParams.Add(param.ID, graphParameter); parameters[i] = graphParameter; } var nodes = FindNode(MainNodeGroupId, MainNodeTypeId) .DepthFirstTraversal() .Select <SurfaceNode, RenderingNode>((surfaceNode, index) => { int[] inputIndices = surfaceNode.Elements .OfType <InputBox>() .Select(inputBox => inputBox.HasAnyConnection ? variableIndexGetter.UseVariable(inputBox) : -1) .ToArray(); int[] outputIndices = surfaceNode.Elements .OfType <OutputBox>() .Select(outputBox => variableIndexGetter.RegisterVariable(outputBox)) .ToArray(); int groupId = surfaceNode.GroupArchetype.GroupID; int typeId = surfaceNode.Archetype.TypeID; if (groupId == paramNodeGroupId) { var graphParam = graphParams[(Guid)surfaceNode.Values[0]]; inputIndices = new int[1] { graphParam.OutputIndex }; } var nodeDefinition = new NodeDefinition() { GroupId = groupId, TypeId = typeId, Index = index, Values = surfaceNode.Values, InputIndices = inputIndices, OutputIndices = outputIndices }; var nodeFactory = GetNodeFactoryGroup(groupId).GetNodeFactory(typeId); return(nodeFactory.Create(nodeDefinition)); }) .ToArray(); graph.Parameters = parameters; graph.Nodes = nodes; }