RegularPyramid.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. using Microsoft.Xna.Framework;
  2. using Microsoft.Xna.Framework.Graphics;
  3. using System;
  4. namespace OpenVIII.Battle
  5. {
  6. /// <summary>
  7. /// base is a rectangle. the top vertex is centered over the base.
  8. /// </summary>
  9. public class RegularPyramid
  10. {
  11. private const float persistentAlpha = .9f;
  12. #region Fields
  13. private static readonly TimeSpan RotationTime = TimeSpan.FromMilliseconds(1500d);
  14. private static readonly TimeSpan FadeTime = TimeSpan.FromMilliseconds(1000);
  15. private BasicEffect effect;
  16. private Matrix offset;
  17. private Slide<float> radians;
  18. private Slide<float> fader;
  19. private VertexPositionColor[] tempVertices;
  20. private VertexPositionColor[] uniqueVertices;
  21. #endregion Fields
  22. #region Constructors
  23. public RegularPyramid()
  24. {
  25. uniqueVertices = new VertexPositionColor[5];
  26. VertexBuffer = new VertexBuffer(Memory.Graphics.GraphicsDevice, uniqueVertices[0].GetType(), 5, BufferUsage.WriteOnly);
  27. Indices = new IndexBuffer(Memory.Graphics.GraphicsDevice, typeof(short), 18, BufferUsage.WriteOnly);
  28. radians = new Slide<float>(0f, MathHelper.TwoPi, RotationTime, MathHelper.Lerp)
  29. {
  30. Repeat = true
  31. };
  32. fader = new Slide<float>(0f, 1f, FadeTime, MathHelper.Lerp);
  33. effect = new BasicEffect(Memory.Graphics.GraphicsDevice);
  34. Set(1, 1, null);
  35. }
  36. #endregion Constructors
  37. #region Properties
  38. private IndexBuffer Indices { get; set; }
  39. private int Triangles { get; set; }
  40. private VertexBuffer VertexBuffer { get; set; }
  41. #endregion Properties
  42. #region Methods
  43. public void Draw(Matrix worldMatrix, Matrix viewMatrix, Matrix projectionMatrix)
  44. {
  45. //donno why but direct x crashes when i try to draw colored primatives.
  46. if (Memory.CurrentGraphicMode == Memory.GraphicModes.DirectX || alpha < float.Epsilon) return;
  47. effect.World = worldMatrix;
  48. effect.View = viewMatrix;
  49. effect.Projection = projectionMatrix;
  50. effect.VertexColorEnabled = true;
  51. effect.Alpha = alpha * persistentAlpha;
  52. //PyramidEffect.EnableDefaultLighting();
  53. Memory.Graphics.GraphicsDevice.SetVertexBuffer(VertexBuffer);
  54. Memory.Graphics.GraphicsDevice.Indices = Indices;
  55. var tmp = Memory.Graphics.GraphicsDevice.RasterizerState;
  56. Memory.Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone;
  57. foreach (var pass in effect.CurrentTechnique.Passes)
  58. {
  59. pass.Apply();
  60. Memory.Graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, Indices.IndexCount);
  61. }
  62. Memory.Graphics.GraphicsDevice.RasterizerState = tmp;
  63. }
  64. public void Set(float height, float basewidth, params Color[] color) => Set(height, basewidth, basewidth, color);
  65. public void Set(float height, float basewidth, float baselength, params Color[] color)
  66. {
  67. if (color == null || color.Length == 0)
  68. {
  69. var c = Color.Yellow;
  70. color = new Color[] { c, c, c, c, c };
  71. }
  72. else if (color.Length < uniqueVertices.Length)
  73. {
  74. var c = color[0];
  75. color = new Color[] { c, c, c, c, c };
  76. }
  77. //techinally there are 5 unique. but everything is triangles.
  78. var bottom = height < 0 ? -height : 0f;
  79. if (height < 0) height = 0;
  80. uniqueVertices[0].Position = new Vector3(0f, height, 0f);
  81. uniqueVertices[0].Color = color[0];
  82. uniqueVertices[1].Position = new Vector3(-basewidth / 2f, bottom, -baselength / 2f);
  83. uniqueVertices[1].Color = color[1];
  84. uniqueVertices[2].Position = new Vector3(-basewidth / 2f, bottom, baselength / 2f);
  85. uniqueVertices[2].Color = color[2];
  86. uniqueVertices[3].Position = new Vector3(basewidth / 2f, bottom, -baselength / 2f);
  87. uniqueVertices[3].Color = color[3];
  88. uniqueVertices[4].Position = new Vector3(basewidth / 2f, bottom, baselength / 2f);
  89. uniqueVertices[4].Color = color[4];
  90. GenerateVertices();
  91. FadeIn();
  92. }
  93. public void Set(Vector3 offset) => this.offset = Matrix.CreateTranslation(offset);
  94. private float alpha;
  95. public void FadeIn()
  96. {
  97. if (fader.Reversed)
  98. {
  99. fader.ReverseRestart();
  100. }
  101. else fader.Restart();
  102. }
  103. public void FadeOut()
  104. {
  105. if (!fader.Reversed)
  106. {
  107. fader.ReverseRestart();
  108. }
  109. else fader.Restart();
  110. }
  111. public void Update()
  112. {
  113. // Update Fade
  114. alpha = fader.Update();
  115. // Update Rotation
  116. var rotation = Matrix.CreateRotationY(radians.Update());
  117. for (var i = 0; i < tempVertices.Length; i++)
  118. {
  119. tempVertices[i].Position = Vector3.Transform(Vector3.Transform(uniqueVertices[i].Position, rotation), offset);
  120. }
  121. VertexBuffer.SetData(tempVertices);
  122. }
  123. private void GenerateVertices()
  124. {
  125. var indices = new short[]
  126. {
  127. //side 1
  128. 0,
  129. 2,
  130. 1,
  131. //side 2
  132. 0,
  133. 4,
  134. 2,
  135. //side 3
  136. 0,
  137. 3,
  138. 4,
  139. //side 4
  140. 0,
  141. 1,
  142. 3,
  143. //base part 1
  144. 1,
  145. 2,
  146. 3,
  147. //base part 2
  148. 2,
  149. 4,
  150. 3,
  151. };
  152. Triangles = indices.Length / 3;
  153. tempVertices = (VertexPositionColor[])uniqueVertices.Clone();
  154. Indices.SetData(indices);
  155. }
  156. public void Hide()
  157. {
  158. FadeOut();
  159. alpha = 0f;
  160. fader.GotoEnd();
  161. }
  162. #endregion Methods
  163. }
  164. }