using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Kav { public class MeshSprite : ICullable { private static readonly int PixelScale = 40; private static readonly short[] Indices = new short[] { 0, 1, 2, 1, 3, 2 }; public Texture2D Texture { get; } public Texture2D Normal { get; } public SpriteBillboardConstraint BillboardConstraint { get; } public IndexBuffer IndexBuffer { get; } public VertexBuffer VertexBuffer { get; } public BoundingBox BoundingBox { get; } public MeshSprite( GraphicsDevice graphicsDevice, Texture2D texture, SpriteBillboardConstraint billboardConstraint ) { Texture = texture; Normal = null; BillboardConstraint = billboardConstraint; IndexBuffer = new IndexBuffer( graphicsDevice, IndexElementSize.SixteenBits, 6, BufferUsage.WriteOnly ); IndexBuffer.SetData(Indices); var vertexArray = GenerateVertexArray(Texture); VertexBuffer = new VertexBuffer( graphicsDevice, typeof(VertexPositionNormalTexture), 4, BufferUsage.WriteOnly ); VertexBuffer.SetData(vertexArray); BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray)); } public MeshSprite( GraphicsDevice graphicsDevice, Texture2D texture, Texture2D normal, SpriteBillboardConstraint billboardConstraint ) { Texture = texture; Normal = normal; BillboardConstraint = billboardConstraint; IndexBuffer = new IndexBuffer( graphicsDevice, IndexElementSize.SixteenBits, 6, BufferUsage.WriteOnly ); IndexBuffer.SetData(Indices); var vertexArray = GenerateVertexArray(Texture); VertexBuffer = new VertexBuffer( graphicsDevice, typeof(VertexPositionNormalTexture), 4, BufferUsage.WriteOnly ); VertexBuffer.SetData(vertexArray); BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray)); } private static VertexPositionNormalTexture[] GenerateVertexArray(Texture2D texture) { VertexPositionNormalTexture[] result = new VertexPositionNormalTexture[4]; result[0].Position = new Vector3(-texture.Width / 2, texture.Height / 2, 0) / PixelScale; result[0].Normal = new Vector3(0, 0, -1); result[0].TextureCoordinate = new Vector2(0, 0); result[1].Position = new Vector3(texture.Width / 2, texture.Height / 2, 0) / PixelScale; result[1].Normal = new Vector3(0, 0, -1); result[1].TextureCoordinate = new Vector2(1, 0); result[2].Position = new Vector3(-texture.Width / 2, -texture.Height / 2, 0) / PixelScale; result[2].Normal = new Vector3(0, 0, -1); result[2].TextureCoordinate = new Vector2(0, 1); result[3].Position = new Vector3(texture.Width / 2, -texture.Height / 2, 0) / PixelScale; result[3].Normal = new Vector3(0, 0, -1); result[3].TextureCoordinate = new Vector2(1, 1); return result; } private static IEnumerable Positions(IEnumerable vertices) { foreach (var vertex in vertices) { yield return vertex.Position; } } } }