BoundingSphereRenderer.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // BoundingSphereRenderer.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using Microsoft.Xna.Framework;
  12. using Microsoft.Xna.Framework.Graphics;
  13. #endregion
  14. namespace BoundingVolumeRendering
  15. {
  16. /// <summary>
  17. /// Provides a set of methods for rendering BoundingSpheres.
  18. /// </summary>
  19. public static class BoundingSphereRenderer
  20. {
  21. private static VertexBuffer vertBuffer;
  22. private static BasicEffect effect;
  23. private static int lineCount;
  24. /// <summary>
  25. /// Initializes the graphics objects for rendering BoundingSpheres.
  26. /// </summary>
  27. /// <param name="graphicsDevice">The graphics device to use when rendering.</param>
  28. /// <param name="sphereResolution">The number of line segments to use for each of the three circles.</param>
  29. public static void Initialize(GraphicsDevice graphicsDevice, int sphereResolution)
  30. {
  31. // create our effect
  32. effect = new BasicEffect(graphicsDevice);
  33. effect.LightingEnabled = false;
  34. effect.VertexColorEnabled = true;
  35. // calculate the number of lines to draw for all circles
  36. lineCount = (sphereResolution + 1) * 3;
  37. // we need two vertices per line, so we can allocate our vertices
  38. VertexPositionColor[] verts = new VertexPositionColor[lineCount * 2];
  39. // compute our step around each circle
  40. float step = MathHelper.TwoPi / sphereResolution;
  41. // used to track the index into our vertex array
  42. int index = 0;
  43. //create the loop on the XY plane first
  44. for (float a = 0f; a < MathHelper.TwoPi; a += step)
  45. {
  46. verts[index++] = new VertexPositionColor(
  47. new Vector3((float)Math.Cos(a), (float)Math.Sin(a), 0f),
  48. Color.Blue);
  49. verts[index++] = new VertexPositionColor(
  50. new Vector3((float)Math.Cos(a + step), (float)Math.Sin(a + step), 0f),
  51. Color.Blue);
  52. }
  53. //next on the XZ plane
  54. for (float a = 0f; a < MathHelper.TwoPi; a += step)
  55. {
  56. verts[index++] = new VertexPositionColor(
  57. new Vector3((float)Math.Cos(a), 0f, (float)Math.Sin(a)),
  58. Color.Red);
  59. verts[index++] = new VertexPositionColor(
  60. new Vector3((float)Math.Cos(a + step), 0f, (float)Math.Sin(a + step)),
  61. Color.Red);
  62. }
  63. //finally on the YZ plane
  64. for (float a = 0f; a < MathHelper.TwoPi; a += step)
  65. {
  66. verts[index++] = new VertexPositionColor(
  67. new Vector3(0f, (float)Math.Cos(a), (float)Math.Sin(a)),
  68. Color.Green);
  69. verts[index++] = new VertexPositionColor(
  70. new Vector3(0f, (float)Math.Cos(a + step), (float)Math.Sin(a + step)),
  71. Color.Green);
  72. }
  73. // now we create the vertex buffer and put the vertices in it
  74. vertBuffer = new VertexBuffer(
  75. graphicsDevice, typeof(VertexPositionColor), verts.Length, BufferUsage.WriteOnly);
  76. vertBuffer.SetData(verts);
  77. }
  78. /// <summary>
  79. /// Draws a BoundingSphere.
  80. /// </summary>
  81. /// <remarks>
  82. /// This method is an extension method (note the 'this' keyword in front of our BoundingSphere parameter).
  83. /// This allows us to either call this method like a static method or like an instance method:
  84. ///
  85. /// BoundingSphereRenderer.Draw(sphere, view, projection);
  86. /// sphere.Draw(view, projection);
  87. /// </remarks>
  88. /// <param name="sphere">The sphere to render.</param>
  89. /// <param name="view">The current view matrix.</param>
  90. /// <param name="projection">The current projection matrix.</param>
  91. public static void Draw(this BoundingSphere sphere, Matrix view, Matrix projection)
  92. {
  93. if (effect == null)
  94. throw new InvalidOperationException("You must call Initialize before you can render any spheres.");
  95. // set the vertex buffer
  96. effect.GraphicsDevice.SetVertexBuffer(vertBuffer);
  97. // update our effect matrices
  98. effect.World = Matrix.CreateScale(sphere.Radius) * Matrix.CreateTranslation(sphere.Center);
  99. effect.View = view;
  100. effect.Projection = projection;
  101. // draw the primitives with our effect
  102. effect.CurrentTechnique.Passes[0].Apply();
  103. effect.GraphicsDevice.DrawPrimitives(PrimitiveType.LineList, 0, lineCount);
  104. }
  105. }
  106. }