public override void SerializeSettings ( GraphSerializationContext ctx ) { base.SerializeSettings (ctx); ctx.writer.Write (aspectRatio); ctx.SerializeVector3 (rotation); ctx.SerializeVector3 (center); ctx.SerializeVector3 ((Vector3)unclampedSize); ctx.writer.Write (nodeSize); // collision collision.SerializeSettings (ctx); ctx.writer.Write (maxClimb); ctx.writer.Write (maxClimbAxis); ctx.writer.Write (maxSlope); ctx.writer.Write (erodeIterations); ctx.writer.Write (erosionUseTags); ctx.writer.Write (erosionFirstTag); ctx.writer.Write (autoLinkGrids); ctx.writer.Write ((int)neighbours); ctx.writer.Write (cutCorners); ctx.writer.Write (penaltyPosition); ctx.writer.Write (penaltyPositionFactor); ctx.writer.Write (penaltyAngle); ctx.writer.Write (penaltyAngleFactor); ctx.writer.Write (penaltyAnglePower); ctx.writer.Write (isometricAngle); ctx.writer.Write (uniformEdgeCosts); ctx.writer.Write (useJumpPointSearch); }
public void SerializeSettings ( GraphSerializationContext ctx ) { ctx.writer.Write ((int)type); ctx.writer.Write (diameter); ctx.writer.Write (height); ctx.writer.Write (collisionOffset); ctx.writer.Write ((int)rayDirection); ctx.writer.Write ((int)mask); ctx.writer.Write ((int)heightMask); ctx.writer.Write (fromHeight); ctx.writer.Write (thickRaycast); ctx.writer.Write (thickRaycastDiameter); ctx.writer.Write (unwalkableWhenNoGround); ctx.writer.Write (use2D); ctx.writer.Write (collisionCheck); ctx.writer.Write (heightCheck); }
public void SerializeExtraInfo () { if (!settings.nodes) return; int totCount = 0; for (int i=0;i<graphs.Length;i++) { if (graphs[i] == null) continue; graphs[i].GetNodes (node => { totCount = Math.Max (node.NodeIndex, totCount); if (node.NodeIndex == -1) { Debug.LogError ("Graph contains destroyed nodes. This is a bug."); } return true; }); } { var stream = new MemoryStream (); var wr = new BinaryWriter (stream); wr.Write (totCount); int c = 0; for (int i=0;i<graphs.Length;i++) { if (graphs[i] == null) continue; graphs[i].GetNodes (node => { c = Math.Max (node.NodeIndex, c); wr.Write (node.NodeIndex); return true; }); } if (c != totCount) throw new Exception ("Some graphs are not consistent in their GetNodes calls, sequential calls give different results."); byte[] bytes = stream.ToArray (); #if NETFX_CORE wr.Dispose(); #else wr.Close (); #endif AddChecksum (bytes); zip.AddEntry ("graph_references"+binaryExt,bytes); } for (int i=0;i<graphs.Length;i++) { if (graphs[i] == null) continue; var stream = new MemoryStream (); var wr = new BinaryWriter (stream); var ctx = new GraphSerializationContext(wr); graphs[i].SerializeExtraInfo (ctx); byte[] bytes = stream.ToArray (); #if NETFX_CORE wr.Dispose(); #else wr.Close (); #endif AddChecksum (bytes); zip.AddEntry ("graph"+i+"_extra"+binaryExt,bytes); stream = new MemoryStream (); wr = new BinaryWriter (stream); ctx = new GraphSerializationContext(wr); graphs[i].GetNodes (delegate (GraphNode node) { node.SerializeReferences (ctx); return true; }); #if NETFX_CORE wr.Dispose(); #else wr.Close (); #endif bytes = stream.ToArray (); AddChecksum (bytes); zip.AddEntry ("graph"+i+"_references"+binaryExt,bytes); } }
public override void DeserializeNode (GraphSerializationContext ctx) { base.DeserializeNode (ctx); v0 = ctx.reader.ReadInt32(); v1 = ctx.reader.ReadInt32(); v2 = ctx.reader.ReadInt32(); }
public virtual void SerializeSettings ( GraphSerializationContext ctx ) { ctx.writer.Write (guid.ToByteArray()); ctx.writer.Write (initialPenalty); ctx.writer.Write (open); ctx.writer.Write (name ?? ""); ctx.writer.Write (drawGizmos); ctx.writer.Write (infoScreenOpen); for ( int i = 0; i < 4; i++ ) { for ( int j = 0; j < 4; j++ ) { ctx.writer.Write (matrix.GetRow(i)[j]); } } }
public override void DeserializeNode (GraphSerializationContext ctx) { base.DeserializeNode (ctx); position = new Int3 (ctx.reader.ReadInt32(), ctx.reader.ReadInt32(), ctx.reader.ReadInt32()); }
public override void DeserializeReferences (GraphSerializationContext ctx) { int count = ctx.reader.ReadInt32(); if (count == -1) { connections = null; connectionCosts = null; } else { connections = new GraphNode[count]; connectionCosts = new uint[count]; for (int i=0;i<count;i++) { connections[i] = ctx.GetNodeFromIdentifier (ctx.reader.ReadInt32()); connectionCosts[i] = ctx.reader.ReadUInt32(); } } }
public override void DeserializeExtraInfo (GraphSerializationContext ctx) { uint graphIndex = (uint)ctx.graphIndex; TriangleMeshNode.SetNavmeshHolder ((int)graphIndex,this); int nodeCount = ctx.reader.ReadInt32(); int vertexCount = ctx.reader.ReadInt32(); if (nodeCount == -1) { nodes = new TriangleMeshNode[0]; _vertices = new Int3[0]; originalVertices = new Vector3[0]; } nodes = new TriangleMeshNode[nodeCount]; _vertices = new Int3[vertexCount]; originalVertices = new Vector3[vertexCount]; for (int i=0;i<vertexCount;i++) { _vertices[i] = new Int3(ctx.reader.ReadInt32(), ctx.reader.ReadInt32(), ctx.reader.ReadInt32()); originalVertices[i] = new Vector3(ctx.reader.ReadSingle(), ctx.reader.ReadSingle(), ctx.reader.ReadSingle()); } bbTree = new BBTree(); for (int i = 0; i < nodeCount;i++) { nodes[i] = new TriangleMeshNode(active); TriangleMeshNode node = nodes[i]; node.DeserializeNode(ctx); node.UpdatePositionFromVertices(); } bbTree.RebuildFrom (nodes); }
public override void SerializeSettings ( GraphSerializationContext ctx ) { base.SerializeSettings (ctx); ctx.writer.Write (characterRadius); ctx.writer.Write (contourMaxError); ctx.writer.Write (cellSize); ctx.writer.Write (cellHeight); ctx.writer.Write (walkableHeight); ctx.writer.Write (maxSlope); ctx.writer.Write (maxEdgeLength); ctx.writer.Write (editorTileSize); ctx.writer.Write (tileSizeX); ctx.writer.Write (nearestSearchOnlyXZ); ctx.writer.Write (useTiles); ctx.writer.Write ((int)relevantGraphSurfaceMode); ctx.writer.Write (rasterizeColliders); ctx.writer.Write (rasterizeMeshes); ctx.writer.Write (rasterizeTerrain); ctx.writer.Write (rasterizeTrees); ctx.writer.Write (colliderRasterizeDetail); ctx.SerializeVector3 (forcedBoundsCenter); ctx.SerializeVector3 (forcedBoundsSize); ctx.writer.Write (mask); ctx.writer.Write (tagMask.Count); for (int i = 0; i < tagMask.Count; i++) { ctx.writer.Write (tagMask[i]); } ctx.writer.Write (showMeshOutline); ctx.writer.Write (showNodeConnections); ctx.writer.Write (terrainSampleSize); ctx.writer.Write (walkableClimb); ctx.writer.Write (minRegionSize); ctx.writer.Write (tileSizeZ); }
public override void SerializeSettings ( GraphSerializationContext ctx ) { base.SerializeSettings (ctx); ctx.SerializeUnityObject ( sourceMesh ); ctx.SerializeVector3 (offset); ctx.SerializeVector3 (rotation); ctx.writer.Write(scale); ctx.writer.Write(accurateNearestNode); }
public override void DeserializeSettings ( GraphSerializationContext ctx ) { base.DeserializeSettings (ctx); sourceMesh = ctx.DeserializeUnityObject () as Mesh; offset = ctx.DeserializeVector3 (); rotation = ctx.DeserializeVector3 (); scale = ctx.reader.ReadSingle(); accurateNearestNode = ctx.reader.ReadBoolean(); }
public override void SerializeExtraInfo (GraphSerializationContext ctx) { if (nodes == null || originalVertices == null || _vertices == null || originalVertices.Length != _vertices.Length) { ctx.writer.Write (-1); ctx.writer.Write (-1); return; } ctx.writer.Write(nodes.Length); ctx.writer.Write(_vertices.Length); for (int i=0;i<_vertices.Length;i++) { ctx.writer.Write (_vertices[i].x); ctx.writer.Write (_vertices[i].y); ctx.writer.Write (_vertices[i].z); ctx.writer.Write (originalVertices[i].x); ctx.writer.Write (originalVertices[i].y); ctx.writer.Write (originalVertices[i].z); } for (int i=0;i<nodes.Length;i++) { nodes[i].SerializeNode (ctx); } }
/** Deserializes extra graph info. * Extra graph info is specified by the graph types. * \see Pathfinding.NavGraph.DeserializeExtraInfo * \note Stored in files named "graph#_extra.binary" where # is the graph number. */ public void DeserializeExtraInfo () { bool anySerialized = false; // Loop through all graphs and deserialize the extra info // if there is any such info in the zip file for (int i=0;i<graphs.Length;i++) { var entry = zip["graph"+i+"_extra"+binaryExt]; if (entry == null) continue; anySerialized = true; var str = new MemoryStream(); entry.Extract (str); str.Seek (0, SeekOrigin.Begin); var reader = new BinaryReader (str); var ctx = new GraphSerializationContext(reader, null, i + graphIndexOffset); // Call the graph to process the data graphs[i].DeserializeExtraInfo (ctx); } if (!anySerialized) { return; } // Sanity check // Make sure the graphs don't contain destroyed nodes int totCount = 0; for (int i=0;i<graphs.Length;i++) { if (graphs[i] == null) continue; graphs[i].GetNodes (delegate (GraphNode node) { totCount = Math.Max (node.NodeIndex, totCount); if (node.NodeIndex == -1) { Debug.LogError ("Graph contains destroyed nodes. This is a bug."); } return true; }); } { // Get the file containing the list of all node indices // This is correlated with the new indices of the nodes and a mapping from old to new // is done so that references can be resolved var entry = zip["graph_references"+binaryExt]; if (entry == null) throw new Exception ("Node references not found in the data. Was this loaded from an older version of the A* Pathfinding Project?"); var str = new MemoryStream(); entry.Extract (str); str.Seek (0, SeekOrigin.Begin); var reader = new BinaryReader (str); int count = reader.ReadInt32(); var int2Node = new GraphNode[count+1]; try { for (int i=0;i<graphs.Length;i++) { if (graphs[i] == null) continue; graphs[i].GetNodes (node => { int2Node[reader.ReadInt32()] = node; return true; }); } } catch (Exception e) { throw new Exception ("Some graph(s) has thrown an exception during GetNodes, or some graph(s) have deserialized more or fewer nodes than were serialized", e); } #if NETFX_CORE reader.Dispose(); #else reader.Close (); #endif // Deserialize node references for (int i=0;i<graphs.Length;i++) { if (graphs[i] == null) continue; entry = zip["graph"+i+"_references"+binaryExt]; if (entry == null) throw new Exception ("Node references for graph " +i + " not found in the data. Was this loaded from an older version of the A* Pathfinding Project?"); str = new MemoryStream(); entry.Extract (str); str.Seek (0, SeekOrigin.Begin); reader = new BinaryReader (str); var ctx = new GraphSerializationContext(reader, int2Node, i + graphIndexOffset); graphs[i].GetNodes (delegate (GraphNode node) { node.DeserializeReferences (ctx); return true; }); } } }
/** Deserializes graph settings. * \note Stored in files named "graph#.json" where # is the graph number. */ public NavGraph[] DeserializeGraphs () { // Allocate a list of graphs to be deserialized graphs = new NavGraph[meta.graphs]; int nonNull = 0; for (int i=0;i<meta.graphs;i++) { // Get the graph type from the metadata we deserialized earlier var tp = meta.GetGraphType(i); // Graph was null when saving, ignore if (System.Type.Equals (tp, null)) continue; nonNull++; var entry = zip["graph"+i+jsonExt]; if (entry == null) throw new FileNotFoundException ("Could not find data for graph "+i+" in zip. Entry 'graph+"+i+jsonExt+"' does not exist"); // Create a new graph of the right type NavGraph graph = data.CreateGraph(tp); graph.graphIndex = (uint)(i + graphIndexOffset); #if !ASTAR_NO_JSON var entryText = GetString(entry); var reader = new JsonReader(entryText,readerSettings); reader.PopulateObject (ref graph); #else var mem = new MemoryStream (); entry.Extract(mem); mem.Position = 0; var reader = new BinaryReader (mem); var ctx = new GraphSerializationContext(reader, null, i + graphIndexOffset); graph.DeserializeSettings (ctx); #endif graphs[i] = graph; if (graphs[i].guid.ToString () != meta.guids[i]) throw new Exception ("Guid in graph file not equal to guid defined in meta file. Have you edited the data manually?\n"+graphs[i].guid+" != "+meta.guids[i]); } // Remove any null entries from the list var compressed = new NavGraph[nonNull]; nonNull = 0; for ( int i=0;i<graphs.Length;i++) { if ( graphs[i] != null ) { compressed[nonNull] = graphs[i]; nonNull++; } } graphs = compressed; return graphs; }
public override void DeserializeSettings ( GraphSerializationContext ctx ) { base.DeserializeSettings (ctx); aspectRatio = ctx.reader.ReadSingle(); rotation = ctx.DeserializeVector3(); center = ctx.DeserializeVector3(); unclampedSize = (Vector2)ctx.DeserializeVector3(); nodeSize = ctx.reader.ReadSingle(); collision.DeserializeSettings(ctx); maxClimb = ctx.reader.ReadSingle(); maxClimbAxis = ctx.reader.ReadInt32(); maxSlope = ctx.reader.ReadSingle(); erodeIterations = ctx.reader.ReadInt32(); erosionUseTags = ctx.reader.ReadBoolean(); erosionFirstTag = ctx.reader.ReadInt32(); autoLinkGrids = ctx.reader.ReadBoolean(); neighbours = (NumNeighbours)ctx.reader.ReadInt32(); cutCorners = ctx.reader.ReadBoolean(); penaltyPosition = ctx.reader.ReadBoolean(); penaltyPositionFactor = ctx.reader.ReadSingle(); penaltyAngle = ctx.reader.ReadBoolean(); penaltyAngleFactor = ctx.reader.ReadSingle(); penaltyAnglePower = ctx.reader.ReadSingle(); isometricAngle = ctx.reader.ReadSingle(); uniformEdgeCosts = ctx.reader.ReadBoolean(); useJumpPointSearch = ctx.reader.ReadBoolean(); }
public override void DeserializeSettings ( GraphSerializationContext ctx ) { base.DeserializeSettings (ctx); characterRadius = ctx.reader.ReadSingle (); contourMaxError = ctx.reader.ReadSingle (); cellSize = ctx.reader.ReadSingle (); cellHeight = ctx.reader.ReadSingle (); walkableHeight = ctx.reader.ReadSingle (); maxSlope = ctx.reader.ReadSingle (); maxEdgeLength = ctx.reader.ReadSingle (); editorTileSize = ctx.reader.ReadInt32 (); tileSizeX = ctx.reader.ReadInt32 (); nearestSearchOnlyXZ = ctx.reader.ReadBoolean (); useTiles = ctx.reader.ReadBoolean (); relevantGraphSurfaceMode = (RelevantGraphSurfaceMode)ctx.reader.ReadInt32 (); rasterizeColliders = ctx.reader.ReadBoolean (); rasterizeMeshes = ctx.reader.ReadBoolean (); rasterizeTerrain = ctx.reader.ReadBoolean (); rasterizeTrees = ctx.reader.ReadBoolean (); colliderRasterizeDetail = ctx.reader.ReadSingle (); forcedBoundsCenter = ctx.DeserializeVector3 (); forcedBoundsSize = ctx.DeserializeVector3 (); mask = ctx.reader.ReadInt32 (); int count = ctx.reader.ReadInt32 (); tagMask = new List<string> (count); for (int i = 0; i < count; i++) { tagMask.Enqueue (ctx.reader.ReadString()); } showMeshOutline = ctx.reader.ReadBoolean (); showNodeConnections = ctx.reader.ReadBoolean (); terrainSampleSize = ctx.reader.ReadInt32 (); // These were originally forgotten but added in an upgrade // To keep backwards compatibility, they are only deserialized // If they exist in the streamed data walkableClimb = ctx.DeserializeFloat (walkableClimb); minRegionSize = ctx.DeserializeFloat (minRegionSize); // Make the world square if this value is not in the stream tileSizeZ = ctx.DeserializeInt (tileSizeX); }
public override void SerializeNode (GraphSerializationContext ctx) { base.SerializeNode (ctx); ctx.writer.Write (position.x); ctx.writer.Write (position.y); ctx.writer.Write (position.z); }
/** Serializes Node Info. * Should serialize: * - Base * - Node Flags * - Node Penalties * - Node * - Node Positions (if applicable) * - Any other information necessary to load the graph in-game * All settings marked with json attributes (e.g JsonMember) have already been * saved as graph settings and do not need to be handled here. * * It is not necessary for this implementation to be forward or backwards compatible. * * \see */ public override void SerializeExtraInfo (GraphSerializationContext ctx) { BinaryWriter writer = ctx.writer; if (tiles == null) { writer.Write (-1); return; } writer.Write (tileXCount); writer.Write (tileZCount); for (int z=0;z<tileZCount;z++) { for (int x=0;x<tileXCount;x++) { NavmeshTile tile = tiles[x + z*tileXCount]; if (tile == null) { throw new System.Exception ("NULL Tile"); //writer.Write (-1); //continue; } writer.Write(tile.x); writer.Write(tile.z); if (tile.x != x || tile.z != z) continue; writer.Write(tile.w); writer.Write(tile.d); writer.Write (tile.tris.Length); for (int i=0;i<tile.tris.Length;i++) writer.Write (tile.tris[i]); writer.Write (tile.verts.Length); for (int i=0;i<tile.verts.Length;i++) { writer.Write (tile.verts[i].x); writer.Write (tile.verts[i].y); writer.Write (tile.verts[i].z); } writer.Write (tile.nodes.Length); for (int i=0;i<tile.nodes.Length;i++) { tile.nodes[i].SerializeNode (ctx); } } } //return NavMeshGraph.SerializeMeshNodes (this,nodes); }
public override void SerializeReferences (GraphSerializationContext ctx) { if (connections == null) { ctx.writer.Write(-1); } else { ctx.writer.Write (connections.Length); for (int i=0;i<connections.Length;i++) { ctx.writer.Write (ctx.GetNodeIdentifier (connections[i])); ctx.writer.Write (connectionCosts[i]); } } }
public override void DeserializeExtraInfo (GraphSerializationContext ctx) { //NavMeshGraph.DeserializeMeshNodes (this,nodes,bytes); BinaryReader reader = ctx.reader; tileXCount = reader.ReadInt32(); if (tileXCount < 0) return; tileZCount = reader.ReadInt32(); tiles = new NavmeshTile[tileXCount * tileZCount]; //Make sure mesh nodes can reference this graph TriangleMeshNode.SetNavmeshHolder (ctx.graphIndex, this); for (int z=0;z<tileZCount;z++) { for (int x=0;x<tileXCount;x++) { int tileIndex = x + z*tileXCount; int tx = reader.ReadInt32(); if (tx < 0) throw new System.Exception ("Invalid tile coordinates (x < 0)"); int tz = reader.ReadInt32(); if (tz < 0) throw new System.Exception ("Invalid tile coordinates (z < 0)"); // This is not the origin of a large tile. Refer back to that tile. if (tx != x || tz != z) { tiles[tileIndex] = tiles[tz*tileXCount + tx]; continue; } var tile = new NavmeshTile (); tile.x = tx; tile.z = tz; tile.w = reader.ReadInt32(); tile.d = reader.ReadInt32(); tile.bbTree = new BBTree (); tiles[tileIndex] = tile; int trisCount = reader.ReadInt32 (); if (trisCount % 3 != 0) throw new System.Exception ("Corrupt data. Triangle indices count must be divisable by 3. Got " + trisCount); tile.tris = new int[trisCount]; for (int i=0;i<tile.tris.Length;i++) tile.tris[i] = reader.ReadInt32(); tile.verts = new Int3[reader.ReadInt32()]; for (int i=0;i<tile.verts.Length;i++) { tile.verts[i] = new Int3 (reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32()); } int nodeCount = reader.ReadInt32(); tile.nodes = new TriangleMeshNode[nodeCount]; //Prepare for storing in vertex indices tileIndex <<= TileIndexOffset; for (int i=0;i<tile.nodes.Length;i++) { var node = new TriangleMeshNode (active); tile.nodes[i] = node; node.DeserializeNode (ctx); node.v0 = tile.tris[i*3+0] | tileIndex; node.v1 = tile.tris[i*3+1] | tileIndex; node.v2 = tile.tris[i*3+2] | tileIndex; node.UpdatePositionFromVertices(); } tile.bbTree.RebuildFrom(tile.nodes); } } }
public override void SerializeNode (GraphSerializationContext ctx) { base.SerializeNode (ctx); ctx.writer.Write(v0); ctx.writer.Write(v1); ctx.writer.Write(v2); }
public override void DeserializeNode (GraphSerializationContext ctx) { base.DeserializeNode (ctx); position = new Int3(ctx.reader.ReadInt32(), ctx.reader.ReadInt32(), ctx.reader.ReadInt32()); gridFlags = ctx.reader.ReadUInt16(); #if ASTAR_LEVELGRIDNODE_FEW_LAYERS gridConnections = ctx.reader.ReadUInt16(); #else gridConnections = ctx.reader.ReadUInt32(); #endif }
/** Deserializes graph type specific node data. * \see SerializeExtraInfo */ public virtual void DeserializeExtraInfo (GraphSerializationContext ctx) { }
public override void SerializeExtraInfo (GraphSerializationContext ctx) { if (nodes == null) { ctx.writer.Write(-1); return; } ctx.writer.Write (nodes.Length); for (int i=0;i<nodes.Length;i++) { nodes[i].SerializeNode(ctx); } }
public virtual void DeserializeSettings ( GraphSerializationContext ctx ) { guid = new Guid(ctx.reader.ReadBytes (16)); initialPenalty = ctx.reader.ReadUInt32 (); open = ctx.reader.ReadBoolean(); name = ctx.reader.ReadString(); drawGizmos = ctx.reader.ReadBoolean(); infoScreenOpen = ctx.reader.ReadBoolean(); for ( int i = 0; i < 4; i++ ) { Vector4 row = Vector4.zero; for ( int j = 0; j < 4; j++ ) { row[j] = ctx.reader.ReadSingle (); } matrix.SetRow (i, row); } }
public override void DeserializeExtraInfo (GraphSerializationContext ctx) { int count = ctx.reader.ReadInt32(); if (count == -1) { nodes = null; return; } nodes = new GridNode[count]; for (int i=0;i<nodes.Length;i++) { nodes[i] = new GridNode (active); nodes[i].DeserializeNode(ctx); } }
public void DeserializeSettings ( GraphSerializationContext ctx ) { type = (ColliderType)ctx.reader.ReadInt32(); diameter = ctx.reader.ReadSingle (); height = ctx.reader.ReadSingle (); collisionOffset = ctx.reader.ReadSingle (); rayDirection = (RayDirection)ctx.reader.ReadInt32 (); mask = (LayerMask)ctx.reader.ReadInt32 (); heightMask = (LayerMask)ctx.reader.ReadInt32 (); fromHeight = ctx.reader.ReadSingle (); thickRaycast = ctx.reader.ReadBoolean (); thickRaycastDiameter = ctx.reader.ReadSingle (); unwalkableWhenNoGround = ctx.reader.ReadBoolean(); use2D = ctx.reader.ReadBoolean(); collisionCheck = ctx.reader.ReadBoolean(); heightCheck = ctx.reader.ReadBoolean(); }
/** Serializes the graph settings to JSON and returns the data */ public byte[] Serialize (NavGraph graph) { #if !ASTAR_NO_JSON // Grab a cached string builder to avoid allocations var output = GetStringBuilder (); var writer = new JsonWriter (output,writerSettings); writer.Write (graph); return encoding.GetBytes (output.ToString()); #else var mem = new System.IO.MemoryStream(); var writer = new System.IO.BinaryWriter(mem); var ctx = new GraphSerializationContext (writer); graph.SerializeSettings (ctx); return mem.ToArray(); #endif }