XNA UK User Group

A helping hand for bedroom coders throughout the land.
in

Brain Dump

  • Sketchup as an XNA modeller

    image

    One of my colleagues pointed out this week that the latest version of Google’s free modeller, Sketchup,  now allows exporting of your models in Collada (*.dae) format. Perhaps many of you already noted this, but it had passed me by so I thought it was worth highlighting here. There are a number of Collada content importers around – including this one from Remi on the Collada forum. Sketchup is a pretty intuitive tool for modelling and is particularly brilliant for low-poly buildings, so I though some of you virtual worlds/RPG types (John?) might be interested to try it out? 

  • Vera’s Top Tips #1 – Checking the elements of a list against one another.

    I’ve been working on my latest game this morning. It requires a rapid 2D collision detection routine for a lot of sprites – a very common requirement – and in the process of researching different methods on the web (in particular, zoning) I have now read the third bit of code that would be a lot quicker with simple optimisation that every budding games developer should have up their virtual sleeve. I thought a brief description of this issue might be useful. Also I thought that some general tricks & tips on useful gaming algorithms might also complement Nemo Krad’s introductory series to games development on this site.

    When comparing the items in a list against one another - such as a in a basic collision detection routine - the simplest approach (and the one I have seen several examples of this morning) is to create 2 nested for loops that simply pile through the collection. The idea is that the outer loop iterates through each element, and the inner loop checks this element against each of the other elements in the list thus:

    for (int i = 0; i < objList.Count; i++ )
    {
        for (int j = 0; j < objList.Count; j++)
        {
            objList[i].Compare(objList[j]);
        }
     
    }

    This obviously works, however there are also 2 rather sub-optimal things going on here.

    1) We are checking the object against itself – which is usually not required.

    2) Much more seriously, we are also checking each pair of objects twice. If we have checked Object A against B, we do not also need to check object B against A, as this is simply repeating the same comparison.

    A quick modification to the inner loop can prevent  both these unnecessary steps. Consider the following:

    for (int i = 0; i < objList.Count; i++ )
    {
        for (int j = i + 1; j < objList.Count; j++)
        {
            objList[i].Compare(objList[j]);
        }
     
    }

    In this code the inner loop now only commences from the array one index on from the current position of the outer loop. So, as the loop progresses, it only deals with comparisons that have not previously been made and it will never check the outer loop index against itself in the inner loop – a very minor change, but it dramatically reduces the number of comparisons and, it seems, is often overlooked. :)

  • Sudoku Solver

     image

    Continuing my ‘tradition’ of slightly unusual XNA projects, this weekend I’ve been knocking up an XBox360 Sudoku solver. I read an interesting article by Julian Bucknell in last month’s PCPlus magazine. Julian provided a very clear description of a simple brute force, depth first, algorithm. When implemented it pretty much boiled down to a single recursive function. It has nailed everything I could get my hands on from the papers over the last couple of days and left me with enough time to have some fun with the GUI (arty-farty photographing of Lego to make a rotating background, amongst other things).

    Anyway, my 360 should now save me several hours each weekend so I can get on with more games programming! I love Sudoku, but it’s such a waste of time…

    ;)

    image

  • Speaker Notes from XBlig-UK 2009

    This is the quickest way to get links up from the speakers from the day. I’ll also add some prettier pages to the XBlig-UK site in due course. In the meantime, to hear more about XBlig-UK 2009, including interviews with some of the speakers mentioned below (not to mention my own dulcet tones), listen to the NxtGenUG Podcast right here.

    image

    So, without further ado, we had a wicked day with the following top presenters:

    • Paul Foster – Talking about the Zune HD & augmented reality using the Goblin API. He has added to details about these and other topics on his blog.
    • Our very own Charles Humphreys (A.K.A. NemoKrad) – Using Blender to create UV mapped game assets. His talk can be downloaded here. But don’t just read this, get on Random Chaos – his blog on this site – it’s *all* good!
    • John Hampson – Discussing the amazing potential of procedural content generation, with some (but not nearly enough in my view, ‘cos he’s just too polite) reference to his amazing Britonia RPG project. His presentation files can also be downloaded here.
    • Dr Nick Hawes – From University of Birmingham’s Department of Computer Science. Nick presented a fantastic overview of AI techniques from the academic literature that are perfect for controlling NPC game characters. His slides can be found here and he also referenced this presentation on the AI in Halo.
    • Steve Miles – Showing us how to look ‘under’ the Spritebatch and how to roll our own to add new capabilities.
    • Dave Bonner – Lead Developer at Dark Omen Games told us about the peaks & pitfalls of the Xbox Live Indie Games publishing process – all from his personal experience with Nebulon, a top 100 downloaded game.
    • Rich Costall – Founding member of NxtGenUG, took Silverlight to a new level by showing its potential as a gaming platform. Along with Pete McGann, Rich created a common game engine for remake of Manic Miner, with the ability to deploy it the Xbox360 or a website.
    • Salvatore Fileccia – Head of Development at Rare games showed the grey hairs resulting from the decision to utilise a real-world physics engine by him and his team in order to create the unique gameplay of Banjo Kazooie – Nuts & Bolts. Well worth the stress in my and my Kid’s view!
    • Edward Powell – Ranting on about something or other. Currently his bugbear seems be ‘why don’t more people let the Content Pipeline take the strain’? Check out my blog article for more.
    • Paul Manzotti – Gave a great overview of the (often under-used) capabilities of XACT to add those essential sounds & music to your games. His demo was really good, despite me wiring up the speakers backwards…
    • John Price – Finished off for us with his ‘Swagphrase’ game. My childhood mates Kris & Dan will be proud that I was the only one who got ‘3D Monster Maze’ for the ZX81 – get in!

    Roll-on Xblig-UK 2010…

    image

  • ZX360

    I’m afraid I’ve been rather wrapped up in the organisation of next month’s XBlig-UK meeting, and the launch of Windows 7 didn’t help matters much by absorbing the remainder of my free time. However I am now typing on my fully 64-bit laptop - finally!

    Obviously the first thing a person of my age does when they fire up their spanking new 64-bit machine is reminisce about their first 8-bit machine!

    It was while wallowing in this sense of nostalgia that I came across this presentation by Chris Hay from last year’s PDC where he has a full-on ZX Spectrum up and running under Silverlight 3 (I think you might have done Silverlight Manic Miner the hard way Rich!). However it turns out that this is built on an earlier project by Jan Jones who has released the source for a fully deployable XBox360-based Spectrum emulator running under XNA! I tracked down Jan via YouTube and he has very kindly resurrected the original project on Codeplex this week, for us to get hold of it. Jan happily acknowledges that this project remains in the early stages of development, but it is nicely structured (using a C# port of Jasper by Adam Davidson & Andrew Pollard) and all ready for getting amongst it, and starting to add some more features.

    What could be more UK & XNA than an XNA ZX Spectrum guys!

    imageIf you’re up and running under Game Studio 3.1 you’ll probably going to need to recreate the project under the new framework. I just added one extra sub-project to the default windows game template to hold the core speccy elements – Z80.cs, Bitmap.cs & Spectrum.cs. You will then need to make some minor modifications to the Main.cs (which replaces game1.cs if you’re using the default class names from the template), the most significant of these is in the Draw method. The original version calls SetData in a 2DTexture that is set to the Graphics device. This is no longer allowed and will throw an exception – in fact MSDN says we shouldn’t really do this at all because we can potentially screw up predicated tiling on the XBox under some circumstances. However for the time being you can resolve this exception by modifying the draw code thus:

    GraphicsDevice.Textures[0] = null;
     
    m_targetTexture.SetData<uint>(
        m_spectrum.ScreenBuffer, 
        0,
        m_targetTexture.Width * m_targetTexture.Height, 
        SetDataOptions.None
        );
     
    GraphicsDevice.Textures[0] = m_targetTexture;

    This unsets the texture from the Graphics Device before injecting its content from the emulator, then you can stick it back. I’m sure there is a cleaner way of doing this, so please add a comment if you have a suggestion. While MSDN says don’t do it, it doesn’t suggest a better alternative!

    The big areas that could do with some improvement are the keyboard mappings (which really need to editable & stored/restored for each specific game) and sound support. I’ve started adding both these – but got horribly distracted once I had Elite playable…  ;)

    image

    Anyway I hope others have as much fun tinkering with this project as I have. If Jan gives me the thumbs up, I’ll post my Game Studio 3.1 project here or on codeplex to get everyone started.

    Don’t forget XBlig-UK next month – currently more than 50 registered attendees and we’ll have to start limiting registrations once we get up to around 70 so don’t miss out…

    E

    Files

    Please find my Game Studio 3.1 update of Jan’s project here. There are lots of places to get hold of SNA files on the web and you can drop them into the ROMs folder in the project root. I’ve added full keyboard mapping, because my kids got well into The Hobbit over the weekend. You need to plug a conventional USB PC keyboard into your Xbox 360 then you’re away, with F1 to cycle through the available SNA files. I’ve also simplified Jan’s project a bit by replacing the XACT project with the newer SoundEffect class (which handles WAVs through the standard content pipeline) but I’m afraid I still can’t get any functional sound support :(

    Thought some of you might like to see this picture of my kids playing The Hobbit on the ZX360. It’s deployed to the 360 in our living room and you can just make out the USB keyboard being put to good use for this classic text-based adventure.

    image

  • A Slightly Different Sort of Brain Dump…

    http://www.youtube.com/v/sOkQTRDk7_k <p><a href="http://www.youtube.com/v/sOkQTRDk7_k">http://www.youtube.com/v/sOkQTRDk7_k</a></p>

    A few months ago, while clearing up my office, I came across a CD entitled ‘MyBrain’. A colleague of mine was studying for his PhD and had needed volunteers to undergo an MRI scan as part of his research. In return for being one of his guinea pigs I kept a copy of the structural scan element of the data he gathered, and promptly did…er… absolutely nothing with it!

    So, having rediscovered the data *years* later, I thought I should finally have a crack at reading & rendering using C# & XNA. I had a number of options to tackle this problem. Amongst the most visually impressing algorithms I have seen, are these demos on Ziggyware. However, I wanted to do more than just produce the best rendering, I wanted to produce a true mesh from the data - for reasons I will get to at the end…

    Data Structure

    The data came in 2 independent files; a *.img file and associated *.hdr file. The data structures of these files turned out to be pretty straightforward - once I’d found a cool free app, MRIcro, which allowed me to browse the image & header files and provided a lot of useful information! Essentially it was quickly clear I could completely ignore the header (*.hdr) file for the purposes of rendering my particular scan image, since all I needed to know was that the data comprised 64 layers of 256x256 images. The images were each of 16-bit integers representing the density of the tissue at each point in space.

    ep09_4770_e2_structural ep09_4770_e2_structural246

    Marching Cubes

    The problem I have with creating a watertight, closed, mesh (well formed with properly coincident triangle edges and no gaps) from data of this sort is that there isn’t really a surface over which to create your mesh. One solution to this is the Marching Cubes algorithm. This approach can be effective at creating a closed mesh over at the boundary of a given density value in your data. I started with the algorithm & C++ code as described by Paul Bourke in this extremely good paper. In this algorithm, a grid is created in the 3D space occupied by the density data. Each corner of this grid is then checked against the data, to see if it is greater, or less, than the target density we are fitting the mesh to. Once we’ve done this for each corner of a cube, we can then see if we need to create triangles were we have located a boundary between corners that are inside, and corners that are outside, of our target density.

      

    A *particularly* useful bit of the code provided by Bourke are the look-up tables for all these permutations of triangles – some examples of which are shown above.

    In the C++ implementation, the code makes extensive use of pointers and I have to admit that I found this to be the first time I *really* missed them in C#. However, I followed the design pretty closely using lists referenced by index instead. I also wanted to create an indexed triangle mesh for rendering as this saves around (or maybe exactly?) 75% of the required vertices and massively improved performance. I noted from Bourke’s description that there is only one vertex created per cube edge, so by keeping track of the shared edges for each neighbouring cube I was able to reuse vertices fairly easily.

     

    STL File Output

    The stereolithography, or STL, file format is an *extremely* simple triangle mesh file format specifically for use in Rapid Prototyping machines. Precise details of the format can be found here, but essentially it has an 80 byte header we can ignore, a 32-bit int for the number of triangles, and then the list of un-indexed triangles comprising 3 vertices (each ending in a 16-bit int, which for all practical purposes can apparently be set to 0). It is probably simplest to look at the code snippet:

    public void SaveSTL(string filename, VertexPositionNormalColor[] vertices, int[] indices)
    {
    System.IO.FileStream fs = System.IO.File.Create(filename);
    System.IO.BinaryWriter bw = new System.IO.BinaryWriter(fs);

    Byte[] header = new Byte[80];
    bw.Write(header);
    UInt32 facet_count = (UInt32)(indices.Length / 3);
    bw.Write(facet_count);
    UInt16 attribute_byte_count = 0;

    for (int i = 0; i < indices.Length; i += 3)
    {
    bw.Write(0.0f);
    bw.Write(0.0f);
    bw.Write(0.0f);
    bw.Write(vertices[indices[i + 2]].Position.X);
    bw.Write(vertices[indices[i + 2]].Position.Y);
    bw.Write(vertices[indices[i + 2]].Position.Z);
    bw.Write(vertices[indices[i + 1]].Position.X);
    bw.Write(vertices[indices[i + 1]].Position.Y);
    bw.Write(vertices[indices[i + 1]].Position.Z);
    bw.Write(vertices[indices[i]].Position.X);
    bw.Write(vertices[indices[i]].Position.Y);
    bw.Write(vertices[indices[i]].Position.Z);
    bw.Write(attribute_byte_count);
    }
    bw.Close();
    fs.Close();
    }

    Ironically (yes I really do it mean that, Tim!), you can see that, having gone to the trouble of producing an indexed triangle mesh for rendering, I now had to undo all the good work to produce a no-nonsense verbose triangle list for the file. :(

    Making Use of the Result

    So why go to all the bother of creating a mesh at all, let alone an STL file? Well courtesy of this RP service, last week I was able to have a model of my brain built in resin! The physical models are built from the same data used in the XNA rendered in the movie above! This picture show the finished models, which are just over an inch in length.

    RPBrain

    Potentially you could do this for any mesh model, although obviously they tend to geared for low-poly count in games so I’m not sure how good they’d come out. Nevertheless, I thought this might be interesting for someone…

    OK, better get back to some more conventional games programming, now my techno ego trip is complete!!

  • Creating a Custom Model Importer

    One of the biggest problems I have when writing games is in creating or acquiring appropriate 3D models to use. In exploring some open source projects for a ship strategy game I’ve been working on, I found this site: Danger from the Deep. I was, in particular, very impressed by the visuals in this game and the models that they use are available independently under a Creative Commons licence. I grabbed a copy of the these models from their download page and took a look at them.

    Some of the older models were simple 3ds files, but in amongst these are some *really nice* models in a custom format created by Luis Barrancos, Thorsten Jorden, Martin Albertstadt & Marco Sarolo. In the \data\objects\ships\corvettes\FlowerClass directory, for example, is FlowerCorvette_RN.ddxml. As the file suffix would suggest, their file format is a nicely structured xml file. Since I like ships :) I thought that this would be a good opportunity to write a custom content importer to bring these ddxml files into my own XNA project.

    Creating a Project

    First we need to create a new project, which will become the viewer for the model that will result from our content importer.

    Creating a Content Pipeline Extension Project

    Next we need to right click the solution and a add a new project to the solution:

    image

    Select the Content Pipeline Extension Library template, give it a sensible name and click OK to add it to our solution.

    image

    By default the resulting project will have a ContentProcessor class already created. For the purposes of this Demo we don’t need this. so you can delete it. Instead we need to add a new ContentImporter class. Once again we can use a template to do this. Right-click the content importer project and select Add->New Item…

    image

    Give the importer a sensible name – in the Demo project provided I called this class DDXMLImporter.cs.

    The DDXML Structure

    If you take a look at the DDXML model file from Danger from the Deep, you’ll see it is a well formed XML file with nodes for material & mesh definitions. The material is principally defined by paths to texture images. For the purposes of this demo, we’re just going to pick up the diffuse file. The mesh is defined by a list of the X, Y, Z positions in all the vertices in a vertices node. The actual triangles are then defined by indices into this vertex list for each corner of the triangle, plus a list of texture coordinates & normals – each stored under an XML node. The snippet below gives you a flavour of it.

    <dftd-model version="1.0">
    <material name="FlowerMatV1" id="0">
    <diffuse color="1 1 1" />
    <specular color="1 1 1" />
    <shininess exponent="65" />
    <map type="diffuse" filename="FlowerCorvette_RN_1942_WA_color.jpg" uscal="1" vscal="1" uoffset="0" voffset="0" angle="0" >
    <skin filename="flowercorvette_rnavy_camo2.jpg" layout="north_atlantic_royal_navy"/>
    <skin filename="flowercorvette_rnavy_camo3.jpg" layout="mediteranean_sea_all_navies"/>
    <skin filename="flowercorvette_rnavy_camo4.jpg" layout="canadian_northatlantic"/>
    <skin filename="flowercorvette_rnavy_camo5.jpg" layout="canadian_coast_na"/>
    </map>
    <map type="normal" filename="FlowerCorvette_RN_1942_WA_bump.jpg" uscal="1" vscal="1" uoffset="0" voffset="0" angle="0" >
    <skin filename="flowercorvette_rnavy_bump2.jpg" layout="canadian_coast_na"/>
    </map>
    <map type="specular" filename="FlowerCorvette_RN_1942_WA_spec.jpg" uscal="1" vscal="1" uoffset="0" voffset="0" angle="0" >
    <skin filename="flowercorvette_rnavy_spec2.jpg" layout="canadian_northatlantic"/>
    <skin filename="flowercorvette_rnavy_spec2.jpg" layout="canadian_coast_na"/>
    </map>
    </material>
    <mesh name="FlowerCorvetteV1Body" id="0" material="0">
    <vertices nr="7234">2.535352 27.580421 -3.336818 2.535352 27.580421 -3.336818 2.535352 27.580421 -3.336818 -2.535351 27.580421 -3.336818 -2.535351 27.580421 -3.336818 -2.535351 27.580421 -3.336818 -2.535351 27.580421 -3.336818 -4.302600 22.158279 -3.575129 -4.302600 22.158279 -3.575129 -4.302600 22.158279 -3.575129 -4.302600 22.158279 -3.575129 4.302601 22.158279 -3.575129 4.302601 22.158279 -3.575129 4.302601 22.158279 -3.575129 5.031166 18.364771 -3.787620 5.031166 18.364771 -3.787620

    Although I’m going to dive right into the importer in-situ within my project, I should point out that debugging the parsing code in this way is a bit a pain. When I wrote this initially, I actually honed the parsing code independently in simple console app first.

    Writing the Importer

    OK so if we take a look at the class stub that the template has created for us, we can see straight away a couple of quick edits. The first thing we need to do is let Game Studio know what we are wanting to end up with from our importer. In this example we want to end up with a data structure we can push into the standard model processor (custom model processing is something we can return to in a future posting) later in the content pipeline. The data structure we want to end up with is a NodeContent class so we can edit the initial using statement thus:

    // TODO: replace this with the type you want to import.
    using TImport = Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent;

    We can also add some sensible descriptions:

    namespace ContentImporter
    {
    [ContentImporter(".ddxml", DisplayName = "DDXML - Danger from the Deep Model", DefaultProcessor = "ModelProcessor")]
    public class DDXMLImporter : ContentImporter<TImport>
    {

    Now we can add the private members we are going to need:

    // The root NodeContent of our model
    private NodeContent m_rootNode;

    // The current mesh being constructed
    private MeshBuilder m_meshBuilder;

    // Identity of current MTL file for reporting errors against
    private ContentIdentity m_mtlFileIdentity;

    // Current material being constructed
    private BasicMaterialContent m_materialContent;

    // All vertex data in the file
    private List<Vector3> m_positions;
    private List<Vector2> m_texCoords;
    private List<Vector3> m_normals;
    private List<int> m_indices;

    // Mapping from mesh positions to the complete list of
    // positions for the current mesh
    private int[] m_positionMap;

    // Indices of vertex channels for the current mesh
    private int m_textureCoordinateDataIndex;
    private int m_normalDataIndex;

    private XmlReader m_reader;

    The crucial ones here are the Meshbuilder and root NodeContent classes (provided by the XNA framework) plus the lists of positions, texture coordinates, normals that we will fill these classes with as we read the file. The mesh is an indexed triangle mesh (the vertex definitions are re-used in multiple triangle descriptions) so we will also need a list of indices into our vertex list and an array of mappings to the positions in the MeshBuilder later on.

    Because the file is an XML format, I can use the standard XmlReader class and I won’t dwell too much on the actual parsing. It’s not really the interesting bit of this discussion and I probably haven’t implemented it anywhere near optimally!

    The entry point for Content Importers is, unsurprisingly, the Import method:

    public override TImport Import(string filename, ContentImporterContext context)
    {
    m_rootNode = new NodeContent();
    m_meshBuilder = null;
    m_rootNode.Identity = new ContentIdentity(filename);

    m_reader = XmlReader.Create(filename, null);
    ParseXMLNodes(m_reader, "");

    return m_rootNode;
    }

    He we create our actual instance of the NodeContent class and give it an identity for debugging. The real work then begins in the ParseXMLNodes method which divvies up nodes & node content to the appropriate methods as it works through the file. For the purposes of this discussion the initially interesting method is StartMesh, which is called when the first Mesh node is found in the file:

    private void StartMesh(string name)
    {
    m_meshBuilder = MeshBuilder.StartMesh(name);
    m_positions = new List<Vector3>();
    m_texCoords = new List<Vector2>();
    m_normals = new List<Vector3>();
    m_indices = new List<int>();

    // Obj files need their winding orders swapped
    m_meshBuilder.SwapWindingOrder = true;

    // Add additional vertex channels for texture coordinates and normals
    m_textureCoordinateDataIndex = m_meshBuilder.CreateVertexChannel<Vector2>(
    VertexChannelNames.TextureCoordinate(0));
    m_normalDataIndex =
    m_meshBuilder.CreateVertexChannel<Vector3>(VertexChannelNames.Normal());
    }

    This initialises the main repositories for the incoming data. Like Obj files, I found by trial & error that I need to reverse the winding order of these files to get the triangles facing the right way. This problem can manifest itself visually as an excessively dark model, missing triangles or a sort of ‘inside-out’ appearance when you twiddle - depending on you rendering settings.

    In our instance of the MeshBuilder object we also add the channels we are going to need for the texture coordinates & normals that form part of our vertex definition.

    Once our mesh is underway, we can expect to start parsing the contents of the vertices (which are positions as far as the importer is concerned), indices, texture coordinates & normals. In the demo project I wrote a little helper class to split the text content of these nodes into vertex2 or vertex3’s and thus fill up our member lists, like so:

    void ParseNodeContent(XmlReader reader, string node_name)
    {
    switch (node_name)
    {
    case "vertices":
    ContentPipelineHelper.ParseVector3List(ref m_positions, reader.Value);
    break;

    case "indices":
    ContentPipelineHelper.ParseIntList(ref m_indices, reader.Value);
    break;

    case "texcoords":
    ContentPipelineHelper.ParseVector2List(ref m_texCoords, reader.Value);
    break;

    case "normals":
    ContentPipelineHelper.ParseVector3List(ref m_normals, reader.Value);
    break;
    }
    }

    Extracting the filename of the diffuse colour map is handled in the parseMap method where we fill in our mtlFileIdentity object:

    private void ParseMap(XmlReader reader)
    {
    if (reader.GetAttribute("type") == "diffuse")
    {
    string filename = reader.GetAttribute("filename");
    m_mtlFileIdentity = new ContentIdentity(filename);
    m_materialContent.Identity = m_mtlFileIdentity;
    m_materialContent.Texture = new ExternalReference<TextureContent>(filename, m_mtlFileIdentity);
    }
    }

    Finally, when we get to the end of our mesh node we need to finish this mesh off ready to start the next one:

    private void FinishMesh()
    {
    m_positionMap = new int[m_positions.Count];
    for (int i = 0; i < m_positions.Count; i++)
    {
    // positionsMap redirects from the original positions in the order
    // they were read from file to indices returned from CreatePosition
    m_positionMap[i] = m_meshBuilder.CreatePosition(m_positions[i]);
    }

    // Set the last material we parsed - this should really come from the ID s
    m_meshBuilder.SetMaterial(m_materialContent);
    // Create the actual triangles in the mesh
    foreach (int index in m_indices)
    {
    // Set channel data for normal for the following vertex.
    // This must be done before calling AddTriangleVertex
    m_meshBuilder.SetVertexChannelData(m_textureCoordinateDataIndex, m_texCoords[index]);
    m_meshBuilder.SetVertexChannelData(m_normalDataIndex, m_normals[index]);
    m_meshBuilder.AddTriangleVertex(m_positionMap[index]);
    }

    MeshContent meshContent = m_meshBuilder.FinishMesh();
    m_rootNode.Children.Add(meshContent);
    m_meshBuilder = null;
    }

    This is perhaps the most complicated method.  Initially we need to fill the m_positionMap array with the index of each positions in the MeshBuilder as we add the positions to it. When we create the actual triangles in a minute, we’re going to need this array to correctly the reference the stored positions. Then we set the material for the mesh and store the actual triangles according to the index list. In each case we also set the appropriate texture coordinate & normal. Once this process is done we can finalise the mesh with FinishMesh and add the returned MeshContent object to our NodeContent object.

    That is it. Hopefully I’ve been able to keep the parsing code to a minimum so that you can see the general structure of an importer fairly clearly.

    Connecting the Importer to our Game Project

    In order for our viewer to use the importer we have created, we must add a reference to the importer project under the Content->References node of the viewer project tree within the solution.

    image

    Under the Projects tab of the Add Reference dialog, select the content importer project we created above.

    Adding the DDXML models to our project

    Now we’re ready to add the actual models to our viewer project.

    One of the simplest ways to add files to your solution is just to drag them using Explorer. Drag the FlowerCorvette_RN.ddxml file from \dangerdeep-data-0.3.0\data\objects\ships\corvettes\FlowerClass\ into the content node of the ContentImporterDemo or viewer project in your solution.

    The DDXML file also defines the texture image that will be used as the diffuse colour texture map for the model (actually they define several, but for the purposes of this demo we’re just going to use the first one). We need to drag the FlowerCorvette_RN_1942_WA_color.jpg from the same folder into the content node to make a copy of it there too. Although this file will be needed indirectly when the content is compiled, we do not need the project to do anything with it directly, so once it has been copied into the correct location you can right-click and select Exclude From Project.

    Setting the Correct Importer & Processor for a Model

    With the DDXML file added to the content, we need to make sure our new DDXML Content Importer is used (you may need to first build your importer project to ensure that our new importer appears in the drop down list of options). The Content Processor will remain the standard Model – XNA Framework option provided by default. Both of these can be set using the Properties dialog. If this is not open, right-click the file in the project tree and select Properties….

    image

    Putting It All Together

    In the demo project provided, I’ve used some components (detailed in my earlier posts) to provide *very* basic camera and twiddling controls (arrow keys - Z,X to zoom).

    Example Models Rendered using XNA

    image image

    Other Bits & Bobs

    I’ve left this project in a pretty raw state because I didn’t want to distract attention from the core topic here, but I’m sure that many of you will spot lots of opportunities to improve this project. The immediately glaring issues are that the file format provides for multiple diffuse colour maps and a normal map – both of which are ignored in my implementation. In addition some of you may notice the main gun turret & propellers are missing from my import of the Corvette. These extra elements can be animated independently and so are structure in a slightly more sophisticated way than my current importer can handle – I leave this as an exercise for the reader to look at ;) please feel free to let us all know of your improvements or corrections to the code provided here.

    Finally – thanks to the Danger from the Deep guys for providing such inspiring models. Please take a look at their game – it is an amazing piece of work.

    Files

    The demo project described in this post can be downloaded here.

  • Components & Services Demo Project

     Hmm... Still getting the hang of blogging. I don't think I attached the files correctly to the last posting. 

     I think you should be able to get the project as a zip file here

  • Game Services

    In this post I want to build on the Game Components that I discussed previously. At the end of my last posting we were left with a DrawableGameComponent, which had its Draw method being called automatically by the main game object. To draw a mesh in this method, however, we’re going to need to know the view & projection matrices to transform our mesh with. These will typically be shared with the other objects we will be rendering and probably ‘owned’ by some sort of camera class. Ideally we want our camera & drawable objects to be entirely decoupled from one another, so that they can be modified, removed or replaced in isolation.

    The GameServicesContainer

    Once again the solution to this problem can be found in the default game class. It has a property called Services that is an implementation of a GameServiceContainer which can manage the functionality offered by one component to another:

    GameServices

    In our example, the camera component can offer the drawable components a view & projection matrix for rendering themselves during their Draw methods.

    Creating Camera & Input Interfaces

    To begin we start by defining an interface that all of our subsequent camera types will offer:

    interface ICameraService
    {
    Matrix View{get;}
    Matrix Projection{get;}
    }

    While we’re at it we can define an abstracted input interface to move the camera around under user control. I find that I often want to create a control system that will accept either gamepad or keyboard input. One way I have achieved this is to abstract the intent of the player from the actual method by which the player indicates their intent. The camera needs to know that the player intends to ‘turn left’ or ‘move right’, but it doesn’t need to know if, to achieve this, they are pressing the left arrow key on the keyboard, moving the left stick of a gamepad or even moving the mouse. So the interface we will use in this example is as follows:

    interface IInputService
    {

    float LookX();
    float LookY();
    float MoveX();
    float MoveY();
    float MoveZ();
    }

    If at a later stage we want to want to change the source of these actions it will be nicely decoupled from the other objects in our game.

    Now that we have defined the information our components are going to exchange via these interfaces, we need to create some objects that actually implement them.

    Structure

    For the purposes of this discussion, we’re going to create 3 classes, all derived from the GameComponent  class I talked about in my last posting. The class holding the mesh we are going to render is derived from the DrawableGameComponent subclass. The two other component classes also each offer the interfaces outlined above. These interfaces define the services that these components will offer the other components in our game. In summary then the class structure of the project will look like this:

    DemoProjectStructure

    The 3D model, input mediation and camera are all dealt with using Game Components, which only communicate with other via the services that they provide or receive through the Game Services container in the main game object (as described above). This makes it easy to maintain or modify our code as the project grows, as there are no direct dependencies between any of these elements.

    Providing A Service

    The first object in the demo project we will look at is the ControlComponent. This simply checks the keyboard or player one controller during its Update method and then offers look or move values via its implementation of the methods from the IInputService interface. Since it is derived from a GameComponent class, it has a Game property that gives us access to its parent game object (in my previous posting I highlighted that a reference to the parent game object is required during a GameComponent’s construction). Using the Game property of the component we can have it register the service it is offering with the game’s Service Container during initialization thus:

    public override void Initialize()
    {
    Game.Services.AddService(typeof(IInputService), this);

    base.Initialize();
    }

    The game’s service container now knows that it can offer the methods defined in an IInputService interface to any components that require them. In our case this will be the camera object.

    Requesting a Service

    If you take a look at the CameraComponent class in my demo project you will see that, in addition to adding its own ICameraService to the game’s Service Container, it also requests an IInputService. For consistency I’ve also had the object access the graphics device via an interface & service. This is another service already offered by the framework by default. The Inialize function for the CameraComponent is, therefore:

    public override void Initialize()
    {
    // Add our own service to the Game Service container
    Game.Services.AddService(typeof(ICameraService), this);

    // Get back the services we require
    IGraphicsDeviceService graphicsservice = (IGraphicsDeviceService)Game.Services.GetService(typeof(IGraphicsDeviceService));
    m_input = (IInputService)Game.Services.GetService(typeof(IInputService));

    m_aspectRatio = (float)graphicsservice.GraphicsDevice.Viewport.Width /
    (float)graphicsservice.GraphicsDevice.Viewport.Height;

    base.Initialize();
    }

    So we have something (mildly) interesting to look at, I have implemented the simple ModelDrawableComponent class that requests a view & projection matrix via the ICameraService, which it then uses to update its internal matrices and use in its Draw method. The two key functions worth highlighting here are:

    public override void Update(GameTime gameTime)
    {
    if (m_camera != null)
    {
    m_projectionMatrix = m_camera.Projection;
    m_viewMatrix = m_camera.View;
    }

    base.Update(gameTime);
    }

    public override void Draw(GameTime gameTime)
    {
    // Copy any parent transforms.
    Matrix[] transforms = new Matrix[m_model.Bones.Count];
    m_model.CopyAbsoluteBoneTransformsTo(transforms);
    GraphicsDevice.RenderState.DepthBufferEnable = true;

    // Draw the model. A model can have multiple meshes, so loop.
    foreach (ModelMesh mesh in m_model.Meshes)
    {
    // This is where the mesh orientation is set, as well as our camera and projection.
    foreach (BasicEffect effect in mesh.Effects)
    {
    effect.EnableDefaultLighting();
    effect.World = transforms[mesh.ParentBone.Index] * m_rotationMatrix * m_translationMatrix;
    effect.View = m_viewMatrix;
    effect.Projection = m_projectionMatrix;
    }
    // Draw the mesh, using the effects set above.
    mesh.Draw();
    }
    base.Draw(gameTime);
    }

    During inialization the component has asked for an ICameraService m_camera. If we successfully receive a reference to this (it is not null) then we can use it get the camera’s matrices for transformation.

    Linking it all together

    Finally, we just need to wire everything up. As has already been mentioned, the individual components know nothing about one another, so all of this wiring occurs in the game object. First I add the ControlComponent that makes its IInputService available via the game object's Services property. Next I add the CameraComponent that requests this service and offers its own ICameraService into the mix. Finally I add the ModelDrawableComponent that uses the ICameraService to draw itself.

    public Game1()
    {
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";

    Components.Add(new Components.ControlComponent(this));
    Components.Add(new Components.CameraComponent(this));
    Components.Add(new Components.ModelDrawableComponent(this));
    }

    That's it! No more code needs to sneak into the game object for us to render a 3D model that we can move around using either the keyboard arrow keys, or the player one gamepad. Crucially, if we need to change the way the movement of the camera should behave, modify the model, change the input controls or add more objects to our scene they can all be dealt with in isolation without affecting other parts of our project. It is very handy to build a library of useful components that you can 'drop in' trivially to new projects immediately from the start - a frame counter, origin indicator, scale grid and text boxes are all the sort of components I'm sure most people need time and time again.

     

    C&SScreenshot

    I’m sure that this discussion will be rather basic for many visitors to this site. It is also worth pointing out the obvious performance overhead in overdoing it on the component front. Rather than making all of your objects individual DrawableComponents, you will more likely want to limit them to higher level object managers or a scene graph. However, I do hope this posting is useful to some people and that the design pattern of components & services, especially if it is new to you, is worth going over in the context of the XNA framework. Let me know your thoughts…

  • Game Components

    Bit of an intro first...

    Well, hello everyone. This is my first post in my shiny new (and first ever) Blog spot. I have to admit to being a bit nervous, but I wanted to put something back into a site that has really helped me out so I hope that at least 1 or 2 of my XNA projects, observations or issues from the last few years of dabbling might be of use to others. I thought I'd kick off with a bit of a summary of the concepts of a Components & Services in XNA to improve the structure, re-usability and maintainability of project. I know that this is likely to be a basic topic for many of you, but it made such an impact on my productivity when I understood & embraced the concepts, that I would like to give anyone new to XNA the heads up right from the outset.

    Now (hopefully) the more interesting bit...

    After previous dabblings in directx, I was pretty pleased to discover that my very first project under XNA came with the key Update & Draw functions already created. What's more they were magically called for me, without all of the win32 shinanigans previously required! I'm guessing that, like me, many of you immediately went on to pack these two functions with 99% of your first game code. I kept this up for about my first 6 projects before I realised that this wasn't... er, very good practice, to say the least!

    Game Component Collection. Property of the default Game class.Firstly, at the beginning of most game projects you need a lot of similar 'boilerplate' code and I was getting a bit fed up at how difficult (and foolish) it was to cut & paste all the required bits of 'wiring up' for each class or piece of functionality from all over the main game object's methods & properties. Secondly, managing the game object's update & draw functions became rapidly & increasingly complicated as I added more functionality to my basic games. Then I came across this Game Component Demo from Mitch Walker, although it is now a bit dated, it is still conveys the potential of components to resolve these issues and I haven't looked back since!

    The idea behind Game Components is to provide a framework for keeping your reusable code in a nicely encapsulated form. The dependencies between these classes can also be managed & de-coupled from one another (using Services, which I will discuss in a separate post) so that they can be removed, altered or replaced in isolation - or even dropped into another completely new projects quickly & easily.

    So how do you begin to use them?

    Well the first clue can be seen if you examine the properties of your default Game class. You can see that there is a Components property. This is a Collection of Game Components and indicates that the location where instances of your components will ultimately end up.

    Creating a Game Component

    OK so lets start with the simple task of creating an class for an object that we wish to render. Typically we would need to create a class with a Draw & Update method and we would call these methods directly from the equivalent functions in our game class. By creating the class as a Game Component and then adding it to the Game object's Game Component Collection, however, we can allow the game to manage this process for us.

    To create a new class based on a Game Component you can use the class template provided with the framework

    • Right Click your project
    • Select Add->New Item...

     

    In my installation the GameComponent template is under the XNA GameStudio3.0 category, in your setup (and according to the MSDN docs) it may be under your 3.1 category instead.

    • Select the Game Component, give it a sensible name and click Add

    You should now find that your new Game Component class has been added to your project. If you take a look at the code you will see 2 overrides:

    public override void Initialize()
    {
    // TODO: Add your initialization code here

    base.Initialize();
    }

    and

    public override void Update(GameTime gameTime)
    {
    // TODO: Add your update code here

    base.Update(gameTime);
    }

    You should also notice that the constructor requires a Game object:

    public class GameComponent1 : Microsoft.Xna.Framework.GameComponent
    {
    public GameComponent1(Game game)
    : base(game)
    {
    // TODO: Construct any child components here
    }

    This will potentially allow your component access to the properties & methods of its containing game class, but in my next post we’ll see how these are best mediated wherever possible using the Game Services design pattern.

    Wiring up your component

    To add your new component to your game, modify the Game object’s constructor thus:

    public Game1()
    {
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";

    Components.Add(new GameComponent1(this));
    }

    Now put a break point on in the Update function of your component and run the game. You should hit the break point pretty much straight away. If you look at the stack you will see that this is being called automatically as part of the game’s own Update function, the equivalent functions from each of the components in the Components collection are called automatically in this way so you will see that also the case for Initialize function too. Already you can hopefully see that structurally you are already in a position to keep the code relating to this object entirely out of your main game class’s methods – a big improvement on my earliest game projects ;)

    Creating a DrawableGameComponent

    You can now also manually modify the inheritance of your game component object so that it is now inherits from the DrawableGameComponent class. This is a subclass of the base GameComponent with additional methods supported by the component framework. For some reason, there is no template provided for this class, but it is pretty handy:

     DrawableGameComponent

    With your object now inheriting  from a DrawableGameComponent you can override the Draw method and pop a break point on it. Now when you run your project you will find that the Update & Draw methods of your component are now both being automatically called by the game object, so long as this object is in its Components collection.

    In my next posting I’ll take a bit of a look at how to get your components ‘talking’ to one another in a way that still maintains a good degree of decoupling using Game Services. I hope this is interesting to those of you getting started on your own libraries of toolsets.