PageRenderTime 136ms CodeModel.GetById 54ms app.highlight 7ms RepoModel.GetById 73ms app.codeStats 0ms

/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>
 19		/// <param name="radius">Radius</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),
 38				                      	MathHelper.Cos(thetaStep), 0) * radius;
 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]);
 63				Vector.Add(ref rotatedVectors[i], ref position,
 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]);
 77				Vector.Add(ref rotatedVectors[i], ref position,
 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>
 94		/// <param name="radius">The radius of the sphere.</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}