using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; namespace OpenVIII.Battle { /// /// base is a rectangle. the top vertex is centered over the base. /// public class RegularPyramid { private const float persistentAlpha = .9f; #region Fields private static readonly TimeSpan RotationTime = TimeSpan.FromMilliseconds(1500d); private static readonly TimeSpan FadeTime = TimeSpan.FromMilliseconds(1000); private BasicEffect effect; private Matrix offset; private Slide radians; private Slide fader; private VertexPositionColor[] tempVertices; private VertexPositionColor[] uniqueVertices; #endregion Fields #region Constructors public RegularPyramid() { uniqueVertices = new VertexPositionColor[5]; VertexBuffer = new VertexBuffer(Memory.Graphics.GraphicsDevice, uniqueVertices[0].GetType(), 5, BufferUsage.WriteOnly); Indices = new IndexBuffer(Memory.Graphics.GraphicsDevice, typeof(short), 18, BufferUsage.WriteOnly); radians = new Slide(0f, MathHelper.TwoPi, RotationTime, MathHelper.Lerp) { Repeat = true }; fader = new Slide(0f, 1f, FadeTime, MathHelper.Lerp); effect = new BasicEffect(Memory.Graphics.GraphicsDevice); Set(1, 1, null); } #endregion Constructors #region Properties private IndexBuffer Indices { get; set; } private int Triangles { get; set; } private VertexBuffer VertexBuffer { get; set; } #endregion Properties #region Methods public void Draw(Matrix worldMatrix, Matrix viewMatrix, Matrix projectionMatrix) { //donno why but direct x crashes when i try to draw colored primatives. if (Memory.CurrentGraphicMode == Memory.GraphicModes.DirectX || alpha < float.Epsilon) return; effect.World = worldMatrix; effect.View = viewMatrix; effect.Projection = projectionMatrix; effect.VertexColorEnabled = true; effect.Alpha = alpha * persistentAlpha; //PyramidEffect.EnableDefaultLighting(); Memory.Graphics.GraphicsDevice.SetVertexBuffer(VertexBuffer); Memory.Graphics.GraphicsDevice.Indices = Indices; var tmp = Memory.Graphics.GraphicsDevice.RasterizerState; Memory.Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone; foreach (var pass in effect.CurrentTechnique.Passes) { pass.Apply(); Memory.Graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, Indices.IndexCount); } Memory.Graphics.GraphicsDevice.RasterizerState = tmp; } public void Set(float height, float basewidth, params Color[] color) => Set(height, basewidth, basewidth, color); public void Set(float height, float basewidth, float baselength, params Color[] color) { if (color == null || color.Length == 0) { var c = Color.Yellow; color = new Color[] { c, c, c, c, c }; } else if (color.Length < uniqueVertices.Length) { var c = color[0]; color = new Color[] { c, c, c, c, c }; } //techinally there are 5 unique. but everything is triangles. var bottom = height < 0 ? -height : 0f; if (height < 0) height = 0; uniqueVertices[0].Position = new Vector3(0f, height, 0f); uniqueVertices[0].Color = color[0]; uniqueVertices[1].Position = new Vector3(-basewidth / 2f, bottom, -baselength / 2f); uniqueVertices[1].Color = color[1]; uniqueVertices[2].Position = new Vector3(-basewidth / 2f, bottom, baselength / 2f); uniqueVertices[2].Color = color[2]; uniqueVertices[3].Position = new Vector3(basewidth / 2f, bottom, -baselength / 2f); uniqueVertices[3].Color = color[3]; uniqueVertices[4].Position = new Vector3(basewidth / 2f, bottom, baselength / 2f); uniqueVertices[4].Color = color[4]; GenerateVertices(); FadeIn(); } public void Set(Vector3 offset) => this.offset = Matrix.CreateTranslation(offset); private float alpha; public void FadeIn() { if (fader.Reversed) { fader.ReverseRestart(); } else fader.Restart(); } public void FadeOut() { if (!fader.Reversed) { fader.ReverseRestart(); } else fader.Restart(); } public void Update() { // Update Fade alpha = fader.Update(); // Update Rotation var rotation = Matrix.CreateRotationY(radians.Update()); for (var i = 0; i < tempVertices.Length; i++) { tempVertices[i].Position = Vector3.Transform(Vector3.Transform(uniqueVertices[i].Position, rotation), offset); } VertexBuffer.SetData(tempVertices); } private void GenerateVertices() { var indices = new short[] { //side 1 0, 2, 1, //side 2 0, 4, 2, //side 3 0, 3, 4, //side 4 0, 1, 3, //base part 1 1, 2, 3, //base part 2 2, 4, 3, }; Triangles = indices.Length / 3; tempVertices = (VertexPositionColor[])uniqueVertices.Clone(); Indices.SetData(indices); } public void Hide() { FadeOut(); alpha = 0f; fader.GotoEnd(); } #endregion Methods } }