#### /Rendering/Basics/Drawing/Sphere.cs

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