/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
- using System;
- using Delta.Utilities.Datatypes;
- using Delta.Utilities.Helpers;
-
- namespace Delta.Rendering.Basics.Drawing
- {
- /// <summary>
- /// Draw 3D spheres with help of this class. They can be drawn as only
- /// outline or filled shape. This has the advantage of optimizing it better.
- /// </summary>
- public static class Sphere
- {
- #region DrawOutline (Static)
- /// <summary>
- /// Draws a 3D sphere with lines. This basically draws 3 circles (one in
- /// each direction) to form a sphere.
- /// </summary>
- /// <param name="position">Position</param>
- /// <param name="radius">Radius</param>
- /// <param name="color">Sphere color</param>
- public static void DrawOutline(Vector position, float radius, Color color)
- {
- int spherePointsDynamic = (int)Math.Max(25, radius);
-
- Vector[] vectors = new Vector[spherePointsDynamic * 2];
- Vector[] rotatedVectors = new Vector[spherePointsDynamic * 2];
-
- float theta = (360f / (spherePointsDynamic - 1));
-
- Vector lastPosition = Vector.Zero;
- for (int i = 0; i < spherePointsDynamic; i++)
- {
- float thetaStep = theta * i;
-
- // Create a point on the "unit circle" but with the "size" of the radius
- // and with the location based on the wished screen position
- Vector sphereVector = new Vector(MathHelper.Sin(thetaStep),
- MathHelper.Cos(thetaStep), 0) * radius;
-
- if (i > 0)
- {
- int startIndex = i * 2;
- vectors[startIndex] = lastPosition;
- vectors[startIndex + 1] = sphereVector;
- rotatedVectors[startIndex] = lastPosition + position;
- rotatedVectors[startIndex + 1] = sphereVector + position;
- }
-
- lastPosition = sphereVector;
- } // for
-
- DrawManager drawInstance = DrawManager.Instance;
- for (int i = 0; i < spherePointsDynamic; i++)
- {
- drawInstance.Draw3DLine(ref rotatedVectors[i * 2 + 0],
- ref rotatedVectors[i * 2 + 1], ref color);
- }
-
- for (int i = 0; i < vectors.Length; i++)
- {
- Vector.TransformNormal(ref vectors[i], ref cachedPitchTransform,
- ref rotatedVectors[i]);
- Vector.Add(ref rotatedVectors[i], ref position,
- out rotatedVectors[i]);
- }
-
- for (int i = 0; i < spherePointsDynamic; i++)
- {
- drawInstance.Draw3DLine(ref rotatedVectors[i * 2 + 0],
- ref rotatedVectors[i * 2 + 1], ref color);
- }
-
- for (int i = 0; i < vectors.Length; i++)
- {
- Vector.TransformNormal(ref vectors[i], ref cachedRollTransform,
- ref rotatedVectors[i]);
- Vector.Add(ref rotatedVectors[i], ref position,
- out rotatedVectors[i]);
- }
-
- for (int i = 0; i < spherePointsDynamic; i++)
- {
- drawInstance.Draw3DLine(ref rotatedVectors[i * 2 + 0],
- ref rotatedVectors[i * 2 + 1], ref color);
- }
- }
- #endregion
-
- #region DrawFilled (Static)
- /// <summary>
- /// Draw a filled sphere in 3d space.
- /// </summary>
- /// <param name="position">The center position of the sphere in 3d.</param>
- /// <param name="radius">The radius of the sphere.</param>
- /// <param name="color">The fill color of the sphere.</param>
- public static void DrawFilled(Vector position, float radius, Color color)
- {
- DrawManager.Instance.DrawSphere(ref position, radius, ref color);
- }
- #endregion
-
- #region Private
-
- #region cachedPitchTransform (Private)
- /// <summary>
- /// The pitch transform for the outline of the sphere is always the
- /// same, so we can speed things up a little by caching this value
- /// the first time.
- /// </summary>
- private static Matrix cachedPitchTransform;
- #endregion
-
- #region cachedRollTransform (Private)
- /// <summary>
- /// The roll transform for the outline of the sphere is always the
- /// same, so we can speed things up a little by caching this value
- /// the first time.
- /// </summary>
- private static Matrix cachedRollTransform;
- #endregion
-
- #endregion
-
- #region Constructors
- /// <summary>
- /// Static constructor for cached values.
- /// </summary>
- static Sphere()
- {
- // Prepare the "raw" rotation
- Quaternion rotationQuaternion =
- Quaternion.CreateFromYawPitchRoll(0, 90, 0);
- // to calculate the "posing" of the model we need to apply the
- // "own rotation"
- cachedPitchTransform = Matrix.FromQuaternion(rotationQuaternion);
-
- rotationQuaternion = Quaternion.CreateFromYawPitchRoll(0, 0, 90);
- cachedRollTransform = Matrix.FromQuaternion(rotationQuaternion);
- }
- #endregion
- }
- }