/// <summary> /// Function to parse the string containing the hull data. /// </summary> /// <param name="data">The string containing the hull data.</param> /// <param name="builder">The polygonal sprite builder used to create the sprite.</param> private static void ParseString(string data, GorgonPolySpriteBuilder builder) { string[] lines = data.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < lines.Length; ++i) { string line = lines[i].Replace("\r", string.Empty).Trim(); string[] components = line.Split(new[] { ',' }, StringSplitOptions.None); // If this line lacks at least 4 components, then we cannot use it. if (components.Length != 4) { continue; } float.TryParse(components[0], NumberStyles.Float, CultureInfo.InvariantCulture, out float x); float.TryParse(components[1], NumberStyles.Float, CultureInfo.InvariantCulture, out float y); float.TryParse(components[2], NumberStyles.Float, CultureInfo.InvariantCulture, out float u); float.TryParse(components[3], NumberStyles.Float, CultureInfo.InvariantCulture, out float v); builder.AddVertex(new GorgonPolySpriteVertex(new DX.Vector2(x, y), GorgonColor.White, new DX.Vector2(u, v))); } }
/// <summary> /// Function to parse the polygon hull string data. /// </summary> /// <param name="renderer">The renderer used to generate the polygonal sprite.</param> /// <param name="polygonHull">The string containing the polygon hull data.</param> /// <returns>The polygon sprite from the polygon hull data.</returns> public static GorgonPolySprite ParsePolygonHullString(Gorgon2D renderer, string polygonHull) { var builder = new GorgonPolySpriteBuilder(renderer); ParseString(polygonHull, builder); return(builder.Anchor(new DX.Vector2(0.5f, 0.5f)) .Build()); }
/// <summary> /// Function to convert a JSON string into a sprite object. /// </summary> /// <param name="renderer">The renderer for the sprite.</param> /// <param name="overrideTexture">The texture to assign to the sprite instead of the texture associated with the name stored in the file.</param> /// <param name="json">The JSON string containing the sprite data.</param> /// <returns>A new <see cref="GorgonPolySprite"/>.</returns> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="renderer"/>, or the <paramref name="json"/> parameter is <b>null</b>.</exception> /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="json"/> parameter is empty.</exception> /// <exception cref="GorgonException">Thrown if the JSON string does not contain sprite data, or there is a version mismatch.</exception> public static GorgonPolySprite FromJson(Gorgon2D renderer, GorgonTexture2DView overrideTexture, string json) { if (renderer == null) { throw new ArgumentNullException(nameof(renderer)); } if (json == null) { throw new ArgumentNullException(nameof(json)); } if (string.IsNullOrWhiteSpace(json)) { throw new ArgumentEmptyException(nameof(json)); } // Set up serialization so we can convert our more complicated structures. var serializer = new JsonSerializer { CheckAdditionalContent = false }; serializer.Converters.Add(new JsonVector2Converter()); serializer.Converters.Add(new JsonVector3Converter()); serializer.Converters.Add(new JsonSize2FConverter()); serializer.Converters.Add(new JsonGorgonColorConverter()); serializer.Converters.Add(new JsonRectangleFConverter()); serializer.Converters.Add(new JsonSamplerConverter(renderer.Graphics)); serializer.Converters.Add(new JsonTexture2DConverter(renderer.Graphics, overrideTexture)); serializer.Converters.Add(new VersionConverter()); // Parse the string so we can extract our header/version for comparison. var jobj = JObject.Parse(json); ulong jsonID = jobj[GorgonSpriteExtensions.JsonHeaderProp].Value <ulong>(); Version jsonVersion = jobj[GorgonSpriteExtensions.JsonVersionProp].ToObject <Version>(serializer); if (jsonID != CurrentFileHeader) { throw new GorgonException(GorgonResult.CannotRead, Resources.GOR2DIO_ERR_JSON_NOT_SPRITE); } if (!jsonVersion.Equals(CurrentVersion)) { throw new GorgonException(GorgonResult.CannotRead, string.Format(Resources.GOR2DIO_ERR_SPRITE_VERSION_MISMATCH, CurrentVersion, jsonVersion)); } GorgonPolySprite workingSpriteData = jobj.ToObject <GorgonPolySprite>(serializer); // We have to rebuild the sprite because it's only data at this point and we need to build up its vertex/index buffers before we can render it. var builder = new GorgonPolySpriteBuilder(renderer); builder.ResetTo(workingSpriteData); return(builder.Build()); }
/// <summary> /// Function to read the sprite data from a stream. /// </summary> /// <param name="stream">The stream containing the sprite.</param> /// <param name="byteCount">The number of bytes to read from the stream.</param> /// <param name="overrideTexture">The texture to assign to the sprite instead of the texture associated with the name stored in the file.</param> /// <returns>A new <see cref="GorgonPolySprite"/>.</returns> protected override GorgonPolySprite OnReadFromStream(Stream stream, int byteCount, GorgonTexture2DView overrideTexture) { var reader = new GorgonChunkFileReader(stream, new[] { CurrentFileHeader }); GorgonBinaryReader binReader = null; var sprite = new GorgonPolySpriteBuilder(Renderer); try { reader.Open(); binReader = reader.OpenChunk(SpriteData); sprite.Anchor(binReader.ReadValue <DX.Vector2>()); // If we do not have alpha test information, then skip writing its data. if (binReader.ReadBoolean()) { sprite.AlphaTest(binReader.ReadValue <GorgonRangeF>()); } reader.CloseChunk(); binReader = reader.OpenChunk(VertexData); int vertexCount = binReader.ReadInt32(); for (int i = 0; i < vertexCount; ++i) { sprite.AddVertex(new GorgonPolySpriteVertex(binReader.ReadValue <DX.Vector2>(), binReader.ReadValue <GorgonColor>(), binReader.ReadValue <DX.Vector2>())); } reader.CloseChunk(); if (reader.Chunks.Contains(TextureData)) { binReader = reader.OpenChunk(TextureData); sprite.Texture(LoadTexture(binReader, overrideTexture, out DX.Vector2 textureOffset, out DX.Vector2 textureScale, out int textureArrayIndex)); sprite.TextureArrayIndex(textureArrayIndex); sprite.TextureTransform(textureOffset, textureScale); reader.CloseChunk(); } if (!reader.Chunks.Contains(TextureSamplerData)) { return(sprite.Build()); } var builder = new GorgonSamplerStateBuilder(Renderer.Graphics); binReader = reader.OpenChunk(TextureSamplerData); binReader.ReadValue(out SampleFilter filter); binReader.ReadValue(out GorgonColor borderColor); binReader.ReadValue(out Comparison compareFunc); binReader.ReadValue(out TextureWrap wrapU); binReader.ReadValue(out TextureWrap wrapV); binReader.ReadValue(out TextureWrap wrapW); binReader.ReadValue(out int maxAnisotropy); binReader.ReadValue(out float minLod); binReader.ReadValue(out float maxLod); binReader.ReadValue(out float mipLodBias); reader.CloseChunk(); sprite.TextureSampler(builder.Wrapping(wrapU, wrapV, wrapW, borderColor) .Filter(filter) .ComparisonFunction(compareFunc) .MaxAnisotropy(maxAnisotropy) .MipLevelOfDetail(minLod, maxLod, mipLodBias) .Build()); return(sprite.Build()); } finally { binReader?.Dispose(); reader.Close(); } }