[XNA] BoundingBox / Sphere Drawing

Started by
4 comments, last by My_Mind_Is_Going 14 years, 1 month ago
Hi Guys, a hopefully quick question. I am making a 3D game of Pong and at the moment use bounding boxes as "Invisible walls" to detect collision. At the Moment, I have set them up and I'm trying to detect a collision between a box and a sphere. However, I cannot tell if the boxes / sphere is in the right place as in debug, they only give, min and max Vectors) , is there a way I can draw this bounding box or bounding sphere so they are visible?
Advertisement
If you want to visualize the bounding boxes you'll need to write some code to do this. I use the following helper class in my projects (note this is written for debugging purposes not efficiency).

    public static class DrawBoundingBox    {        static Effect effect;        static VertexPositionColor[] verts;                static VertexDeclaration decl;        static void Init(GraphicsDevice device)        {            Debug.Assert(decl == null);            effect = AssetManager.GetEffect("LineRendering", true);            verts = new VertexPositionColor[24];            for (int i = 0; i < verts.Length; i++)            {                verts.Color = Color.Yellow;            }            decl = new VertexDeclaration(device, VertexPositionColor.VertexElements);        }        public static void Draw(GraphicsDevice device, BoundingBox box, ref Matrix viewproj)        {            if (decl == null)                Init(device);            Vector3 min = box.Min;            Vector3 max = box.Max;            verts[0].Position = new Vector3(min.X, min.Y, min.Z);            verts[1].Position = new Vector3(max.X, min.Y, min.Z);            verts[2].Position = new Vector3(min.X, min.Y, max.Z);            verts[3].Position = new Vector3(max.X, min.Y, max.Z);            verts[4].Position = new Vector3(min.X, min.Y, min.Z);            verts[5].Position = new Vector3(min.X, min.Y, max.Z);            verts[6].Position = new Vector3(max.X, min.Y, min.Z);            verts[7].Position = new Vector3(max.X, min.Y, max.Z);            verts[8].Position = new Vector3(min.X, max.Y, min.Z);            verts[9].Position = new Vector3(max.X, max.Y, min.Z);            verts[10].Position = new Vector3(min.X, max.Y, max.Z);            verts[11].Position = new Vector3(max.X, max.Y, max.Z);            verts[12].Position = new Vector3(min.X, max.Y, min.Z);            verts[13].Position = new Vector3(min.X, max.Y, max.Z);            verts[14].Position = new Vector3(max.X, max.Y, min.Z);            verts[15].Position = new Vector3(max.X, max.Y, max.Z);            verts[16].Position = new Vector3(min.X, min.Y, min.Z);            verts[17].Position = new Vector3(min.X, max.Y, min.Z);            verts[18].Position = new Vector3(max.X, min.Y, min.Z);            verts[19].Position = new Vector3(max.X, max.Y, min.Z);            verts[20].Position = new Vector3(min.X, min.Y, max.Z);            verts[21].Position = new Vector3(min.X, max.Y, max.Z);            verts[22].Position = new Vector3(max.X, min.Y, max.Z);            verts[23].Position = new Vector3(max.X, max.Y, max.Z);            effect.Parameters["worldViewProj"].SetValue(viewproj);            effect.Begin();                        EffectPass pass = effect.CurrentTechnique.Passes[0];            pass.Begin();                device.VertexDeclaration = decl;                device.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, verts, 0, 12);            pass.End();            effect.End();        }    }


This assumes the bounding box is in world coordinates. The shader here can be very simple, just transform the vertex and slap on the vertex color.
The Primitives3D samples shows you how to draw cubes and spheres. All you need to is set an appropriate world matrix, and set RenderStates.FillMode = FillMode.WireFrame.

To come up with a world matrix for a bounding box, you just need the center point and a scale value. The center of a bounding box is just the midpoint of the Min/Max, and the scale is just the XYZ distance from the center to the max (or min).
Vector3 centerPos = (boundingBox.Max + boundingBox.Min) / 2;Vector3 scale = boundingBox.Max - centerPos;Matrix world = Matrix.CreateScale(scale);world.Translation = centerPos;


A bounding sphere is even easier. You already know the center point, and the scale is just the radius.
Matrix world = Matrix.CreateScale(boundingSphere.Radius);world.Translation = boundingSphere.Center;
@My_Mind_is_Going

Thank you for the code, but i am having a problem with AssetManager i cannot find any documentation on the internet. is it a class you made or am i forgeting a reference?
Here ya go, 5 classes for drawing lines, 3d points, bounding boxes and bounding spheres and a renderer class to call
It's a bit long to post everything here so I uploaded it
http://www.megaupload.com/?d=EJP3YEX5

The only thing you have to change are the view and projection matrices in Points, Line and Sphere to your own. Then just call
Renderer.BoundingSphere3D.Draw(bs, color);
Renderer.Line3D.Draw(point1, point2, color);
etc
Quote:Original post by Andy474
@My_Mind_is_Going

Thank you for the code, but i am having a problem with AssetManager i cannot find any documentation on the internet. is it a class you made or am i forgeting a reference?


Sorry, yeah that's one of my classes. All that's doing is grabbing an Effect object out of a list I keep them in. You could replace that call with something like Content.Load<Effect>("youreffectname") using the regular XNA ContentManager class.

Edit:

Here's the code for the "LineRendering" shader:

float4x4 worldViewProj : WorldViewProjection;struct VertexInput{	float3 pos   : POSITION;	float4 color : COLOR;};struct VertexOutput {   float4 pos   : POSITION;   float4 color : COLOR;};VertexOutput LineRenderingVS(VertexInput In){	VertexOutput Out;	Out.pos = mul(float4(In.pos, 1), worldViewProj);	Out.color = In.color;		return Out;} float4 LineRenderingPS(VertexOutput In) : Color{	return In.color;} technique LineRendering3D{	pass pass1	{		VertexShader = compile vs_1_1 LineRenderingVS();		PixelShader = compile ps_1_1 LineRenderingPS();	} }

This topic is closed to new replies.

Advertisement