Hello and welcome to the first actual post on the ‘No More Coins‘ blog.
I’m using this post to document a new venture into XNA. I’m coding a new layer into XNA adding extra functionality to support my game programming needs. That and a set of tools I’ll hopefully get the chance to make sometime in the future are lovingly called the XNAlchemist Engine. This is based on another older project still WIP called The Alchemist, a basic multiplatform game engine in C++.
Ok, so besides the fundamental classes and wrappers the first hot topic to touch in development is, of course, Scene Management.
Not very exciting, I know! But even though its not all bells and whistles it’ll definitely pay off in the future. Good foundations and all that jazz…
From the many techniques for scene management, I decided two were crucial enough to implement at this stage: Octrees and Portals.
The daddy class for all scenes, alScene3D defines the concept of a scene as a set of 3D objects with a given implementation, bounding and position/orientation/scale. It inherits (indirectly) from DrawableComponent so rendering and updating a scene can be done by XNA’s component manager. It inherits directly from alDrawableObject3D (note: al is a prefixe used for all Alchemist classes) that basically defines it as a 3D object with a position, orientation, scale, and bounding. Also to note that scenes store alDrawableObject3D, so scenes with different spacial management can be nested (as you will see from the mixed approach later in this post).
This class is an implementation of the alScene3D class with an octree spacial division. An octree is basicaly a tree structure where each node divides its space into 8 octants (8 divisions), this is done to improve performance in culling, collision detection and so on. This implementation takes into account a maximum and minimum resolution so even though the example below shows a linear octree, it is capable of supporting non-linearity. Another parameter it takes into account is a buffer limit, so if the buffer of a particular area is full it will be divided into smaller nodes until each node is within the buffer limit or just over (or equal to) the minimum resolution.
The example below is a linear octree (with a fixed number of divisions) where only nodes that contain geometry are shown, if they’re not culled by the camera’s frustum anyway. Also note that I’m constantly freezing frustum culling to show which nodes are actually being drawn. I will do that in all the videos throughout the post.
This class, as you might have guessed, is an implementation ofÂ alScene3D with portal culling. Portal culling is the process of dividing a scene into areas (aka. zones, rooms, etc.) and determining which areas are visible by testing the camera frustum against visible portals. Imagine rooms and finding out which rooms are visible is done by determining which doors you can see from where you are at. This is obviously ideal for indoor environments.
This implementation allows a user to define areas and portals and link them to each other to form the scene. Then, from the current area, portals connected to that area are tested for visibility and the process then iterates through other visible areas linked to those portals, and so on. On each of these steps a portal is tested against the space visible from the previous portal and the camera’s frustum. This, however, is not done in screenspace. Instead a projection matrix is built and used as a custom frustum that represents the visible area through a given portal.
This last example combines the above mentioned techniques.
As I mentioned, a 3D scene is a child of alDrawableObjec3D that is responsible for managing and rendering a set of 3D objects (also alDrawableObject3D), meaning a scene can be nested within a scene.
Remember when I mentioned that portal testing was done with custom frustums instead of screenspace? Well, this is the main reason for that. Using frustums has a little bonus to it, you see each area contains its calculated custom frustum which can be passed through to other functions, like rendering for example.
When drawing (or updating, to be more specific) a given area, alScene3DPortals replaces the view frustum (which is generally the active camera’s viewing frustum) with the area’s custom frustum. This way, only objects in the octree scene visible through the portals in the portal scene will be drawn, as shown from the example below.
And that’s that.
I hope this was somehow interesting or useful. These ‘Back to the Basic‘ posts will cover the basic aspects of developing XNAlchemist. I’ll try and keep all the work (that’s actually worth watching) posted here. I appreciate any feedback and thank everyone for the support.
There are still a few optimizations to do but I’ll soon move to a much more exciting topic… graphics!
See you then!
Thank you for reading!
Leave a Reply