Here's one way to do it if you don't mind taking advantage of XNA's API, which should work for every case. I can think of a few alternatives but they would involve doing more calculations manually, by taking advantage of the fact that your camera is orthogonal (i.e. the BoundingFrustum is just a box too).
Step 1) Store BoundingSphere (or BoundingBox) for each model
You can create the BoundingSphere using the following helper method:
BoundingSphere boundingSphere = BoundingSphere.CreateFromPoints(model.Vertices);
Ideally this should be done in the content processor and stored in the model, but you can also do it at load time. Don't forget to also Transform the BoundingSphere whenever you move the model.
Step 2) Create a BoundingFrustum for your camera
The constructor takes the ViewProrjectionMatrix:
BoundingFrustum frustum = new BoundingFrustum(viewMatrix * projectionMatrix);
Step 3) Check for Intersection
Draw only the models whose BoundingSpheres intersect (or are contained) by the BoundingFrustum:
models.Where(m => frustum.Contains(m.BoundingSphere) != ContainmentType.Disjoint).Draw();
Extra Notes (Edit)
I'd like to add a few notes. First the BoundingFrustum
check is the simplest way to implement it because it's already provided for you by XNA. But it's not the most efficient for this case because, since your camera is orthogonal the frustum could be stored as a normal BoundingBox
. Unfortunately there's no built in way to get this BoundingBox calculated for you automatically. Personally, I wouldn't bother with it until I noticed any performance issues.
Also, one advantage of using a BoundingSphere
versus a BoundingBox
for your models (like I commented on Ciarian's post) is that you can easily "move it along" with the model (even when it rotates or scales). This is because for translation you only need to move the center of the sphere, for scaling you only need to scale the radius, and for rotation you don't need to do anything. It's so simple that XNA already has a method for it, i.e. BoundingSphere.Transform()
.
The BoundingBox
class on the other hand, doesn't have this facility because it must remain axis aligned. To properly transform an axis aligned bounding box, you need to transform all of its corners and then fit a new bounding box around them!
Some people may tell you to simply transform the BoundingBox
's Min and Max values, but that is not correct and you'd run into trouble with transformed models - this is a very common pitfall. I repeat,don't transform an AABB just by transforming its Min/Max values. I made this picture that shows this problem in 2D but it's exactly the same thing in 3D:
