Rendering Bounding Spheres
From XNAWiki
This is a basic static class that allows easy rendering of BoundingSpheres.
/// <summary>
/// Provides a set of methods for rendering BoundingSpheres.
/// </summary>
public static class BoundingSphereRenderer
{
static VertexBuffer vertBuffer;
static VertexDeclaration vertDecl;
static BasicEffect effect;
static int sphereResolution;
/// <summary>
/// Initializes the graphics objects for rendering the spheres. If this method isn't
/// run manually, it will be called the first time you render a sphere.
/// </summary>
/// <param name="graphicsDevice">The graphics device to use when rendering.</param>
/// <param name="sphereResolution">The number of line segments
/// to use for each of the three circles.</param>
public static void InitializeGraphics(GraphicsDevice graphicsDevice, int sphereResolution)
{
BoundingSphereRenderer.sphereResolution = sphereResolution;
vertDecl = new VertexDeclaration(graphicsDevice, VertexPositionColor.VertexElements);
effect = new BasicEffect(graphicsDevice, null);
effect.LightingEnabled = false;
effect.VertexColorEnabled = false;
VertexPositionColor[] verts = new VertexPositionColor[(sphereResolution + 1) * 3];
int index = 0;
float step = MathHelper.TwoPi / (float)sphereResolution;
//create the loop on the XY plane first
for (float a = 0f; a <= MathHelper.TwoPi; a += step)
{
verts[index++] = new VertexPositionColor(
new Vector3((float)Math.Cos(a), (float)Math.Sin(a), 0f),
Color.White);
}
//next on the XZ plane
for (float a = 0f; a <= MathHelper.TwoPi; a += step)
{
verts[index++] = new VertexPositionColor(
new Vector3((float)Math.Cos(a), 0f, (float)Math.Sin(a)),
Color.White);
}
//finally on the YZ plane
for (float a = 0f; a <= MathHelper.TwoPi; a += step)
{
verts[index++] = new VertexPositionColor(
new Vector3(0f, (float)Math.Cos(a), (float)Math.Sin(a)),
Color.White);
}
vertBuffer = new VertexBuffer(
graphicsDevice,
verts.Length * VertexPositionColor.SizeInBytes,
BufferUsage.None);
vertBuffer.SetData(verts);
}
/// <summary>
/// Renders a bounding sphere using different colors for each axis.
/// </summary>
/// <param name="sphere">The sphere to render.</param>
/// <param name="graphicsDevice">The graphics device to use when rendering.</param>
/// <param name="view">The current view matrix.</param>
/// <param name="projection">The current projection matrix.</param>
/// <param name="xyColor">The color for the XY circle.</param>
/// <param name="xzColor">The color for the XZ circle.</param>
/// <param name="yzColor">The color for the YZ circle.</param>
public static void Render(
BoundingSphere sphere,
GraphicsDevice graphicsDevice,
Matrix view,
Matrix projection,
Color xyColor,
Color xzColor,
Color yzColor)
{
if (vertBuffer == null)
InitializeGraphics(graphicsDevice, 30);
graphicsDevice.VertexDeclaration = vertDecl;
graphicsDevice.Vertices[0].SetSource(
vertBuffer,
0,
VertexPositionColor.SizeInBytes);
effect.World =
Matrix.CreateScale(sphere.Radius) *
Matrix.CreateTranslation(sphere.Center);
effect.View = view;
effect.Projection = projection;
effect.DiffuseColor = xyColor.ToVector3();
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
//render each circle individually
graphicsDevice.DrawPrimitives(
PrimitiveType.LineStrip,
0,
sphereResolution);
effect.DiffuseColor = xzColor.ToVector3();
effect.CommitChanges();
graphicsDevice.DrawPrimitives(
PrimitiveType.LineStrip,
sphereResolution + 1,
sphereResolution);
effect.DiffuseColor = yzColor.ToVector3();
effect.CommitChanges();
graphicsDevice.DrawPrimitives(
PrimitiveType.LineStrip,
(sphereResolution + 1) * 2,
sphereResolution);
pass.End();
}
effect.End();
}
/// <summary>
/// Renders a bounding sphere using a single color for all three axis.
/// </summary>
/// <param name="sphere">The sphere to render.</param>
/// <param name="graphicsDevice">The graphics device to use when rendering.</param>
/// <param name="view">The current view matrix.</param>
/// <param name="projection">The current projection matrix.</param>
/// <param name="color">The color to use for rendering the circles.</param>
public static void Render(
BoundingSphere sphere,
GraphicsDevice graphicsDevice,
Matrix view,
Matrix projection,
Color color)
{
if (vertBuffer == null)
InitializeGraphics(graphicsDevice, 30);
graphicsDevice.VertexDeclaration = vertDecl;
graphicsDevice.Vertices[0].SetSource(
vertBuffer,
0,
VertexPositionColor.SizeInBytes);
effect.World =
Matrix.CreateScale(sphere.Radius) *
Matrix.CreateTranslation(sphere.Center);
effect.View = view;
effect.Projection = projection;
effect.DiffuseColor = color.ToVector3();
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
//render each circle individually
graphicsDevice.DrawPrimitives(
PrimitiveType.LineStrip,
0,
sphereResolution);
graphicsDevice.DrawPrimitives(
PrimitiveType.LineStrip,
sphereResolution + 1,
sphereResolution);
graphicsDevice.DrawPrimitives(
PrimitiveType.LineStrip,
(sphereResolution + 1) * 2,
sphereResolution);
pass.End();
}
effect.End();
}
}