PageRenderTime 36ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/Rendering/Basics/Drawing/Sphere.cs

#
C# | 142 lines | 88 code | 19 blank | 35 comment | 7 complexity | 512baf5ad2b578a33ef91f8b2625eba0 MD5 | raw file
Possible License(s): Apache-2.0
  1. using System;
  2. using Delta.Utilities.Datatypes;
  3. using Delta.Utilities.Helpers;
  4. namespace Delta.Rendering.Basics.Drawing
  5. {
  6. /// <summary>
  7. /// Draw 3D spheres with help of this class. They can be drawn as only
  8. /// outline or filled shape. This has the advantage of optimizing it better.
  9. /// </summary>
  10. public static class Sphere
  11. {
  12. #region DrawOutline (Static)
  13. /// <summary>
  14. /// Draws a 3D sphere with lines. This basically draws 3 circles (one in
  15. /// each direction) to form a sphere.
  16. /// </summary>
  17. /// <param name="position">Position</param>
  18. /// <param name="radius">Radius</param>
  19. /// <param name="color">Sphere color</param>
  20. public static void DrawOutline(Vector position, float radius, Color color)
  21. {
  22. int spherePointsDynamic = (int)Math.Max(25, radius);
  23. Vector[] vectors = new Vector[spherePointsDynamic * 2];
  24. Vector[] rotatedVectors = new Vector[spherePointsDynamic * 2];
  25. float theta = (360f / (spherePointsDynamic - 1));
  26. Vector lastPosition = Vector.Zero;
  27. for (int i = 0; i < spherePointsDynamic; i++)
  28. {
  29. float thetaStep = theta * i;
  30. // Create a point on the "unit circle" but with the "size" of the radius
  31. // and with the location based on the wished screen position
  32. Vector sphereVector = new Vector(MathHelper.Sin(thetaStep),
  33. MathHelper.Cos(thetaStep), 0) * radius;
  34. if (i > 0)
  35. {
  36. int startIndex = i * 2;
  37. vectors[startIndex] = lastPosition;
  38. vectors[startIndex + 1] = sphereVector;
  39. rotatedVectors[startIndex] = lastPosition + position;
  40. rotatedVectors[startIndex + 1] = sphereVector + position;
  41. }
  42. lastPosition = sphereVector;
  43. } // for
  44. DrawManager drawInstance = DrawManager.Instance;
  45. for (int i = 0; i < spherePointsDynamic; i++)
  46. {
  47. drawInstance.Draw3DLine(ref rotatedVectors[i * 2 + 0],
  48. ref rotatedVectors[i * 2 + 1], ref color);
  49. }
  50. for (int i = 0; i < vectors.Length; i++)
  51. {
  52. Vector.TransformNormal(ref vectors[i], ref cachedPitchTransform,
  53. ref rotatedVectors[i]);
  54. Vector.Add(ref rotatedVectors[i], ref position,
  55. out rotatedVectors[i]);
  56. }
  57. for (int i = 0; i < spherePointsDynamic; i++)
  58. {
  59. drawInstance.Draw3DLine(ref rotatedVectors[i * 2 + 0],
  60. ref rotatedVectors[i * 2 + 1], ref color);
  61. }
  62. for (int i = 0; i < vectors.Length; i++)
  63. {
  64. Vector.TransformNormal(ref vectors[i], ref cachedRollTransform,
  65. ref rotatedVectors[i]);
  66. Vector.Add(ref rotatedVectors[i], ref position,
  67. out rotatedVectors[i]);
  68. }
  69. for (int i = 0; i < spherePointsDynamic; i++)
  70. {
  71. drawInstance.Draw3DLine(ref rotatedVectors[i * 2 + 0],
  72. ref rotatedVectors[i * 2 + 1], ref color);
  73. }
  74. }
  75. #endregion
  76. #region DrawFilled (Static)
  77. /// <summary>
  78. /// Draw a filled sphere in 3d space.
  79. /// </summary>
  80. /// <param name="position">The center position of the sphere in 3d.</param>
  81. /// <param name="radius">The radius of the sphere.</param>
  82. /// <param name="color">The fill color of the sphere.</param>
  83. public static void DrawFilled(Vector position, float radius, Color color)
  84. {
  85. DrawManager.Instance.DrawSphere(ref position, radius, ref color);
  86. }
  87. #endregion
  88. #region Private
  89. #region cachedPitchTransform (Private)
  90. /// <summary>
  91. /// The pitch transform for the outline of the sphere is always the
  92. /// same, so we can speed things up a little by caching this value
  93. /// the first time.
  94. /// </summary>
  95. private static Matrix cachedPitchTransform;
  96. #endregion
  97. #region cachedRollTransform (Private)
  98. /// <summary>
  99. /// The roll transform for the outline of the sphere is always the
  100. /// same, so we can speed things up a little by caching this value
  101. /// the first time.
  102. /// </summary>
  103. private static Matrix cachedRollTransform;
  104. #endregion
  105. #endregion
  106. #region Constructors
  107. /// <summary>
  108. /// Static constructor for cached values.
  109. /// </summary>
  110. static Sphere()
  111. {
  112. // Prepare the "raw" rotation
  113. Quaternion rotationQuaternion =
  114. Quaternion.CreateFromYawPitchRoll(0, 90, 0);
  115. // to calculate the "posing" of the model we need to apply the
  116. // "own rotation"
  117. cachedPitchTransform = Matrix.FromQuaternion(rotationQuaternion);
  118. rotationQuaternion = Quaternion.CreateFromYawPitchRoll(0, 0, 90);
  119. cachedRollTransform = Matrix.FromQuaternion(rotationQuaternion);
  120. }
  121. #endregion
  122. }
  123. }