<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type='text/xsl' href='http://rhysyngsun.spaces.live.com/mmm2008-05-17_13.22/rsspretty.aspx?rssquery=en-US;http%3a%2f%2frhysyngsun.spaces.live.com%2fcategory%2fXNA%2ffeed.rss' version='1.0'?><rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:msn="http://schemas.microsoft.com/msn/spaces/2005/rss" xmlns:live="http://schemas.microsoft.com/live/spaces/2006/rss" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Nathan Levesque - Developer/Designer: XNA</title><description /><link>http://rhysyngsun.spaces.live.com/?_c11_BlogPart_BlogPart=blogview&amp;_c=BlogPart&amp;partqs=catXNA</link><language>en-US</language><pubDate>Thu, 15 May 2008 14:43:44 GMT</pubDate><lastBuildDate>Thu, 15 May 2008 14:43:44 GMT</lastBuildDate><generator>Microsoft Spaces v1.1</generator><docs>http://www.rssboard.org/rss-specification</docs><ttl>60</ttl><cf:parentRSS>http://rhysyngsun.spaces.live.com/blog/feed.rss</cf:parentRSS><live:type>blogcategory</live:type><live:identity><live:id>-306981137987202659</live:id><live:alias>rhysyngsun</live:alias></live:identity><cf:listinfo><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="typelabel" label="Type" /><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="tag" label="Tag" /><cf:group element="category" label="Category" /><cf:sort element="pubDate" label="Date" data-type="date" default="true" /><cf:sort element="title" label="Title" data-type="string" /><cf:sort ns="http://purl.org/rss/1.0/modules/slash/" element="comments" label="Comments" data-type="number" /></cf:listinfo><item><title>The Key is Back in the Ignition</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!194.entry</link><description>So to speak.

I've decided to separate XNA content back out to this blog again. Partly because I want separation of content and partly because the other blog is now being aggregated by sites that do not cater to XNA.

More to come.

Using the XNA 3.0 CTP.&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+The+Key+is+Back+in+the+Ignition&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!194.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!194.entry</guid><pubDate>Thu, 15 May 2008 14:43:44 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!194/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!194.entry#comment</wfw:comment><dcterms:modified>2008-05-15T14:43:44Z</dcterms:modified></item><item><title>Back in the Running</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!165.entry</link><description>&lt;p&gt;Ok, so I've taken the last week to get used to my new Vista computer. So far I love the new operating system and can't wait to get some DX10 games (played the DX10 PC demo of Lost Planet today and it was absolutely great). I'm getting excellent framerates on all of the games I already own too. &lt;p&gt;In the meantime I'm working on yet another rewrite of my game engine. It's getting a little ridiculous to keep rewriting every three weeks or so but I think this is a very robust version. Today I coded my own implementation of the GameScreen idea and integrated it with a post processing batch class. My post processing framework has the ability to basically render any object that implements a interface that has only a Draw method. &lt;p&gt;I'm not sure if I'm going to finish my game in time for the Dream-Build-Play contest deadline, but I'm going to try my best to at least have something remotely playable to submit. ;)&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+Back+in+the+Running&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!165.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!165.entry</guid><pubDate>Thu, 14 Jun 2007 16:16:27 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!165/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!165.entry#comment</wfw:comment><dcterms:modified>2007-06-14T16:16:27Z</dcterms:modified></item><item><title>Update</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!164.entry</link><description>&lt;p&gt;Ok, so at present I am waiting until Monday until the parts arrive for me to assemble a new Vista PC for me. This has been a long time coming and frankly I don't know how I'm going to make it through the weekend since UPS doesn't deliver on the weekend and the package will be sitting not an hour's drive away from here for the next two days!  &lt;p&gt;Since my development of my XNA game is on hold until that PC is up and running ( mostly cause I'm sick of developing on 6-year-old DX8 hardware), I've decided to make myself a little project for the weekend and that is the beginnings of a physics component. I've seen this requested on the XNA forums and my plans are that if I get this working and it is somewhere near publishable I will release both source and assemblies for the public to download. As such, I'm taking my time and trying to comment and document as much as I can while still making reasonable progress. &lt;p&gt;So far what I've got going: &lt;ul&gt; &lt;li&gt;Active and passive rigid bodies. These are presently held in a custom collection I designed to make handling rigid bodies easier. Actual collisions have yet to be coded. Planning on adding support to use any combination of: BoundingSpheres, BoundingBoxes, and Models to handle collisions. First two will be easy, Models not so much.  &lt;li&gt;Extensible fields system such as gravity, vortex, wind (keeping it simple for now, these are relatively simple to add).  &lt;li&gt;Some kind of dynamic system will be added later on for springs and such.&lt;/ul&gt; &lt;p&gt;I hope to have a video demo up tomorrow night since I'm going to implement some simple BoundingBox collisions first and see how that goes. &lt;p&gt;Keep an eye out for it ;)&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+Update&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!164.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!164.entry</guid><pubDate>Sat, 02 Jun 2007 06:04:33 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!164/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!164.entry#comment</wfw:comment><dcterms:modified>2007-06-02T06:04:46Z</dcterms:modified></item><item><title>Matrix Tutorial</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!163.entry</link><description>&lt;p&gt;Not gonna post it in full here cause I'm lazy but I submitted an article at Ziggyware's &lt;p&gt;&lt;a href="http://www.ziggyware.com/readarticle.php?article_id=100"&gt;Introduction to Matrices in XNA&lt;/a&gt; &lt;blockquote&gt; &lt;p&gt;Understanding matrices is a fundamental part of creating effective games in XNA. Matrices particularly flex their muscle when you're working in full 3D space, however, the math behind them can be daunting. Fortunately, XNA provides most of the functionality for matrices that you will ever need without having to worry about the complicated math behind that functionality. However, it is necessary to have an understanding of what this functionality is actually doing in order to apply it correctly in your code. This article is rather long winded, but I'm trying to give a thorough explanation which will allow you to fully grasp the power of matrices. &lt;/blockquote&gt; &lt;p&gt;Also I've been rather busy lately with my code, I've once again changed my mind on what I intend to do (I've been working on developing the basics of an engine so far, not worrying about content yet). I'm back to working on an RTS game since I don't feel like dealing with FPS code at the moment.&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+Matrix+Tutorial&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!163.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!163.entry</guid><pubDate>Mon, 21 May 2007 00:22:25 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!163/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!163.entry#comment</wfw:comment><dcterms:modified>2007-05-21T00:22:25Z</dcterms:modified></item><item><title>XNA Refresh Trick #1: Autoformatting Multiple Lines of Text</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!158.entry</link><description>&lt;p&gt;So by now everyone is very happy I'm sure of the release of XNA Refresh. It comes with a slew of additions to the framework that everyone has been clamoring for. Particularly font, 3d audio, and Model vertex reading support. &lt;p&gt;I've been putting off my GUI because I didn't want to redesign once the XNA team's font support came out, here's the first trick I created, to help myself with my GUI: autoformatting multiple lines of text. If you look into the documentation it says that the new text functionality will go the a new line with the text if the '\n' character is found. However, this makes for some static game design. What if I want the text block to be wider? Well, the way to do this is to add '\n' characters at runtime. Here's the little method I developed to do this:&lt;pre&gt;&lt;span style="color:rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;void&lt;/span&gt; SetTextWidth( &lt;span style="color:rgb(0,0,255)"&gt;ref&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;string&lt;/span&gt; text, &lt;span style="color:rgb(43,145,175)"&gt;SpriteFont&lt;/span&gt; spriteFont, &lt;span style="color:rgb(0,0,255)"&gt;float&lt;/span&gt; width )
{
    &lt;span style="color:rgb(0,128,0)"&gt;// get a vector representing the size of our string
&lt;/span&gt;    &lt;span style="color:rgb(43,145,175)"&gt;Vector2&lt;/span&gt; textSize = spriteFont.MeasureString( text );

    &lt;span style="color:rgb(0,128,0)"&gt;// if text already fits, don't do anything
&lt;/span&gt;    &lt;span style="color:rgb(0,0,255)"&gt;if&lt;/span&gt; ( textSize.X &amp;lt; width )
        &lt;span style="color:rgb(0,0,255)"&gt;return&lt;/span&gt;;

    &lt;span style="color:rgb(0,128,0)"&gt;// remove existing newline chars in case it has already been formatted
&lt;/span&gt;    text = text.Replace( &lt;span style="color:rgb(163,21,21)"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;, &lt;span style="color:rgb(163,21,21)"&gt;&amp;quot;&amp;quot;&lt;/span&gt; );

    &lt;span style="color:rgb(0,128,0)"&gt;// loop through all characters in string, if a character extends past our width
&lt;/span&gt;    &lt;span style="color:rgb(0,0,255)"&gt;float&lt;/span&gt; lineTotal = 0;
    &lt;span style="color:rgb(0,0,255)"&gt;float&lt;/span&gt; wordTotal = 0;
    &lt;span style="color:rgb(0,0,255)"&gt;int&lt;/span&gt; charCount = 0;
    &lt;span style="color:rgb(0,0,255)"&gt;int&lt;/span&gt; i = 0;
    &lt;span style="color:rgb(0,0,255)"&gt;do
&lt;/span&gt;    {
        &lt;span style="color:rgb(0,128,0)"&gt;// if we find whitespace, we're reached the end of a word
&lt;/span&gt;        &lt;span style="color:rgb(0,0,255)"&gt;if&lt;/span&gt; ( &lt;span style="color:rgb(0,0,255)"&gt;char&lt;/span&gt;.IsWhiteSpace( text, i ) )
        {
            &lt;span style="color:rgb(0,128,0)"&gt;// measure the length of the word
&lt;/span&gt;            wordTotal = spriteFont.MeasureString( text.Substring( i - charCount, charCount ) ).X;
            &lt;span style="color:rgb(0,128,0)"&gt;// if the word extends past our width, we insert
&lt;/span&gt;            &lt;span style="color:rgb(0,128,0)"&gt;// a \n before the word to pop it to the next line
&lt;/span&gt;            &lt;span style="color:rgb(0,0,255)"&gt;if&lt;/span&gt; ( ( lineTotal + wordTotal ) &amp;gt; width &amp;amp;&amp;amp; lineTotal != 0 )
            {
                text = text.Insert( i - charCount, &lt;span style="color:rgb(163,21,21)"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt; );
                lineTotal = wordTotal;
                charCount = 0;
            }
            &lt;span style="color:rgb(0,128,0)"&gt;// otherwise the word fits on our current line
&lt;/span&gt;            &lt;span style="color:rgb(0,0,255)"&gt;else
&lt;/span&gt;            {
                lineTotal += wordTotal + 1;
                charCount = 0;
                i++;
            }
        }
        &lt;span style="color:rgb(0,0,255)"&gt;else
&lt;/span&gt;        {
            charCount++;
            i++;
        }             
    } &lt;span style="color:rgb(0,0,255)"&gt;while&lt;/span&gt; ( i &amp;lt; text.Length );
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Now this method isn't entirely robust, for instance it won't hyphenate words that are too long to fit on a single line, instead it just prints the whole word out, extendeding past our designated width. Feel free to change this, but for my case I wasn't concerned about being able to print 30 character words correctly (and I hope, netiher are you for your gamer's sake ;) ).
&lt;p&gt;Here's a little preview of the results I can get with this method(single string used):
&lt;p&gt;&lt;a href="http://tk2.storage.msn.com/x1ppUPyqopddk5J2Pnzw16-NNkZJq8Q1Qyvcr-ep7eAY08I3-tZSee5ioVM_1OYC8nzlD4YKx3M7GNlo35uD0GZggPEfmmEaE5gM1LRtCOQZvDEyqUbVbOunbzWV1X8Jv0hnpK4nxCcqZrcNx7b15phsQ"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px" height=116 src="http://tkfiles.storage.msn.com/x1pppQPzd7N2QxK7TYd_KG5IP0WVhWDT4GkIs-KwWCBNtob-WGxImVQ_rtjmtFzxEObIYOqIU4s_h-Ix666w6wlz1X0IS0VNpwpaaz6dFdIt8o" width=240 border=0&gt;&lt;/a&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+XNA+Refresh+Trick+%231%3a+Autoformatting+Multiple+Lines+of+Text&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!158.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!158.entry</guid><pubDate>Thu, 26 Apr 2007 12:56:47 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!158/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!158.entry#comment</wfw:comment><dcterms:modified>2007-04-26T12:59:44Z</dcterms:modified></item><item><title>XNA 1.0 Refresh Update Released!</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!140.entry</link><description>&lt;p&gt;The XNA Team announced the release of their Refresh update for XNA today: &lt;p&gt;&lt;a title="http://blogs.msdn.com/xna/archive/2007/04/24/xna-game-studio-express-1-0-refresh-released.aspx" href="http://blogs.msdn.com/xna/archive/2007/04/24/xna-game-studio-express-1-0-refresh-released.aspx"&gt;http://blogs.msdn.com/xna/archive/2007/04/24/xna-game-studio-express-1-0-refresh-released.aspx&lt;/a&gt; &lt;p&gt;I've only taken a cursory glance at the changes they've made, and needless to say I'm very pleased. I've already been able to make changes to my code that I've been waiting for this update to make. Particularly of interest to, and many others are the inclusion of text drawing and 3d audio! &lt;p&gt;I'd also suggest taking a good look through the docs, there's a lot of new topics, particularly in the &amp;quot;Programming Guide&amp;quot; section. &lt;p&gt;So, with the addition of the text drawing methods, I'm off to resume work on my GUI! &lt;p&gt;Thank you XNA Team for all your hard work!&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+XNA+1.0+Refresh+Update+Released!&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!140.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!140.entry</guid><pubDate>Tue, 24 Apr 2007 18:33:30 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!140/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!140.entry#comment</wfw:comment><dcterms:modified>2007-04-24T18:33:30Z</dcterms:modified></item><item><title>A Better GetService</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!139.entry</link><description>&lt;p&gt;Ok, so recently there's been a lot of major discussion on the XNA forums about GameComponents. Now, I love the idea of having integrated components that automatically get get updated and also drawn in the case of DrawableGameComponent, however, when it comes to accessing the Game class's Services. I also have at issue being able to access said Services in a class that is not a GameComponent. I understand the XNA's team for making the services the way they are, however I don't want to have to derive from GameComponent and add it to the GameComponentCollection every time I want to check to have access to the ContentManager or whatever. For the most part, input components are the only issue that I have with the way Services are set up. &lt;p&gt;This simple class helps both Component and non-Component classes alike. Now, what this code avoids is having to type code like this every time you want to access a Service:&lt;pre&gt;&lt;span style="color:rgb(0, 128, 128)"&gt;ContentManager&lt;font color="#000000"&gt; manager =&lt;/font&gt; &lt;/span&gt;(&lt;span style="color:rgb(0, 128, 128)"&gt;ContentManager&lt;/span&gt;)Game.Services.GetService( &lt;span style="color:rgb(0, 0, 255)"&gt;typeof&lt;/span&gt;( &lt;span style="color:rgb(0, 128, 128)"&gt;ContentManager &lt;/span&gt;) )&lt;/pre&gt;
&lt;p&gt;That can quickly become time consuming and can add to the illegibility of the code, not to mention either having multiple lines of code for one call or having to scroll horizontally a bit. So what I've decided to do is create a simple static class that stores the current game and has a generic method called GetService that functions similarly to Services.GetService():&lt;pre&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;static&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;class&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;Component&lt;br&gt;&lt;/span&gt;{&lt;br&gt;    &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;static&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;Game&lt;/span&gt; Game;&lt;br&gt;&lt;br&gt;    &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;static&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;void&lt;/span&gt; SetGame( &lt;span style="color:rgb(0, 128, 128)"&gt;Game&lt;/span&gt; game )&lt;br&gt;    {&lt;br&gt;        Game = game;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;static&lt;/span&gt; T GetService&amp;lt;T&amp;gt;()&lt;br&gt;    {&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;return&lt;/span&gt; (T)Game.Services.GetService( &lt;span style="color:rgb(0, 0, 255)"&gt;typeof&lt;/span&gt;( T ) );&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;
&lt;p&gt;Now, what we do is call Component.SetGame(this); in the Initalize method of our derived game class (Game1 in a new project). Then every time we need a service in a non-component class, we simply call:&lt;pre&gt;&lt;span style="color:rgb(0, 128, 128)"&gt;ContentManager&lt;font color="#000000"&gt; manager =&lt;/font&gt; Component&lt;/span&gt;.GetService&amp;lt;&lt;span style="color:rgb(0, 128, 128)"&gt;&lt;span style="color:rgb(0, 128, 128)"&gt;ContentManager&lt;/span&gt;&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;p&gt;Now this might not be the most elegant solution, but it appears to work well enough in my code.&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+A+Better+GetService&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!139.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!139.entry</guid><pubDate>Mon, 16 Apr 2007 02:38:40 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!139/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!139.entry#comment</wfw:comment><dcterms:modified>2007-04-16T02:39:10Z</dcterms:modified></item><item><title>XNA Octree Tutorial</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!129.entry</link><description>&lt;p&gt;This tutorial may be a bit wordy, but I've tried to give a fair amount of detail as to what is going on in the code. If you're fairly familiar with XNA code, particularly BoundingBoxes, you can probably just skim the code itself and understand it just as quick if not quicker than I explain it. This is still very fresh code, not thoroughly tested, but I feel confident enough to share it. For everyone else, here we go! &lt;p&gt;First of all, what exactly is an octree? An octree is a spatial partitioning system that divides a cube recursively into eight equally sized cubes until each cube contains a specified number of polygons or objects. This tree can then be used to quickly determine visibility or to quickly rule out objects for physics purposes. For the purposes of XNA, I've designed my system to be used on a per-object basis. &lt;p&gt;Since this tutorial is being done with XNA in mind, we're going to try to use as much of XNA's built-in functionality to ease design time. First of all we need to define what the structure of the nodes or &amp;quot;leaves&amp;quot; in this tree. This will be similar to the structure you might see in a scene graph, however each node can represent multiple objects and will always either no child nodes or 8.&lt;pre&gt;&lt;span style="color:rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf
&lt;/span&gt;{
    &lt;span style="color:rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;const&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;int&lt;/span&gt; maxobj = 8;
    &lt;span style="color:rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:rgb(0,128,128)"&gt;SceneObject&lt;/span&gt;&amp;gt; containedObjects;&lt;br&gt;    &lt;span style="color:rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt;&amp;gt; childLeaves;&lt;br&gt;    &lt;span style="color:rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt; containerBox;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="color:rgb(0,0,255)"&gt;&lt;br&gt;    &lt;br&gt;    public&lt;/span&gt; OctreeLeaf( &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt; containerBox )
    {
        &lt;span style="color:rgb(0,0,255)"&gt;this&lt;/span&gt;.containedObjects = &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:rgb(0,128,128)"&gt;Geometry&lt;/span&gt;&amp;gt;();
        &lt;span style="color:rgb(0,0,255)"&gt;this&lt;/span&gt;.childLeaves = &lt;span style="color:rgb(0,0,255)"&gt;null&lt;/span&gt;;
        &lt;span style="color:rgb(0,0,255)"&gt;this&lt;/span&gt;.containerBox = containerBox;
    }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Here we've begun by defining our class, OctreeLeafwhich has the following fields:
&lt;ul&gt;
&lt;li&gt;maxobj - this is the maximum number of objects a single leaf can contain 
&lt;li&gt;containedObjects - a List&amp;lt;&amp;gt; of the scene objects that the particular node contains. 
&lt;li&gt;childLeaves - a List&amp;lt;&amp;gt; of child OctreeLeafs. These leaves are exactly contained with the current OctreeLeaf. 
&lt;li&gt;containerBox - this is where the primary functionality of our Octree is based on. We will be using the built-in functions of the BoundingBox structure to to do most of the work for us.&lt;/ul&gt;
&lt;p&gt;For the purposes of this tutorial I am going to assume that the SceneObject has a property of type BoundingBox named BoundingBox
&lt;p&gt;Our Constructor is passed a BoundingBox that specifies its size and initializes fields accordingly. We don't know if we have any children yet, so we initialize childLeaves to null.
&lt;p&gt;I also added the following properties to the class:&lt;pre&gt;    &lt;span style="color:rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:rgb(0,128,128)"&gt;Geometry&lt;/span&gt;&amp;gt; ContainedObjects
    {
        &lt;span style="color:rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color:rgb(0,0,255)"&gt;return&lt;/span&gt; containedObjects; }
        &lt;span style="color:rgb(0,0,255)"&gt;set&lt;/span&gt; { containedObjects = &lt;span style="color:rgb(0,0,255)"&gt;value&lt;/span&gt;; }
    }&lt;br&gt;
    &lt;span style="color:rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt;&amp;gt; ChildLeaves
    {
        &lt;span style="color:rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color:rgb(0,0,255)"&gt;return&lt;/span&gt; childLeaves; }
    }

    &lt;span style="color:rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt; ContainerBox
    {
        &lt;span style="color:rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color:rgb(0,0,255)"&gt;return&lt;/span&gt; containerBox; }
        &lt;span style="color:rgb(0,0,255)"&gt;set&lt;/span&gt; { containerBox = &lt;span style="color:rgb(0,0,255)"&gt;value&lt;/span&gt;; }
    }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Next we need to provide some functionality to add 8 child leaves and size them so they are each exactly half the size of our current containerBox. This vector math is rather dirty, and I'm probably missing an easier way to do this, but as of now it does the job:&lt;pre&gt;&lt;span style="color:rgb(0,0,255)"&gt;    protected&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;void&lt;/span&gt; Split()
    {
        &lt;span style="color:rgb(0,128,128)"&gt;Vector3&lt;/span&gt; half = ContainerBox.Max - ContainerBox.Min;
        &lt;span style="color:rgb(0,128,128)"&gt;Vector3&lt;/span&gt; halfx = &lt;span style="color:rgb(0,128,128)"&gt;Vector3&lt;/span&gt;.UnitX * half;
        &lt;span style="color:rgb(0,128,128)"&gt;Vector3&lt;/span&gt; halfy = &lt;span style="color:rgb(0,128,128)"&gt;Vector3&lt;/span&gt;.UnitY * half;
        &lt;span style="color:rgb(0,128,128)"&gt;Vector3&lt;/span&gt; halfz = &lt;span style="color:rgb(0,128,128)"&gt;Vector3&lt;/span&gt;.UnitZ * half;

        ChildLeaves.Add( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt;( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt;( ContainerBox.Min, ContainerBox.Min + half ) ) );
        ChildLeaves.Add( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt;( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt;( ContainerBox.Min + halfx, ContainerBox.Max - half + halfx ) ) );
        ChildLeaves.Add( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt;( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt;( ContainerBox.Min + halfz, ContainerBox.Min + half + halfz ) ) );
        ChildLeaves.Add( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt;( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt;( ContainerBox.Min + halfx + halfz, ContainerBox.Max - halfy ) ) );
        ChildLeaves.Add( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt;( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt;( ContainerBox.Min + halfy, ContainerBox.Max - halfx - halfz ) ) );
        ChildLeaves.Add( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt;( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt;( ContainerBox.Min + halfy + halfx, ContainerBox.Max - halfz ) ) );
        ChildLeaves.Add( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt;( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt;( ContainerBox.Min + halfy + halfz, ContainerBox.Max - halfx ) ) );
        ChildLeaves.Add( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt;( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt;( ContainerBox.Min + half, ContainerBox.Max ) ) );
    }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;I made this a protected method because we never call this outside the class, only within our method that distributes the objects. This method grabs a Vector3 that represents the half size of the cube and then creates width, height and length vectors (halfx, halfy, and halfz, respectively) by multiplying by the three unit vectors. The rest is pretty straightforward, if a bit confusing. Basically I've hardcoded the creation of each half-sized box. Probably a better way, but for now it suffices.
&lt;p&gt;Now, we need to give our OctreeLeaf class the ability to distribute objects:&lt;pre&gt;&lt;span style="color:rgb(0,0,255)"&gt;    public&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;void&lt;/span&gt; Distribute()
    {
        &lt;span style="color:rgb(0,0,255)"&gt;if&lt;/span&gt; ( containedObjects.Count &amp;gt; maxobj )
        {
            Split();
            &lt;span style="color:rgb(0,0,255)"&gt;for&lt;/span&gt; ( &lt;span style="color:rgb(0,0,255)"&gt;int&lt;/span&gt; i = ContainedObjects.Count; i &amp;gt; 0; i-- )
            {
                &lt;span style="color:rgb(0,0,255)"&gt;foreach&lt;/span&gt; ( &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt; leaf &lt;span style="color:rgb(0,0,255)"&gt;in&lt;/span&gt; ChildLeaves )
                {
                    &lt;span style="color:rgb(0,0,255)"&gt;if&lt;/span&gt; ( leaf.ContainerBox.Contains( ContainedObjects[i].BoundingBox ) == &lt;span style="color:rgb(0,128,128)"&gt;ContainmentType&lt;/span&gt;.Contains )
                    {
                        leaf.ContainedObjects.Add( ContainedObjects[i] );
                        containedObjects.Remove( ContainedObjects[i] );
                        &lt;span style="color:rgb(0,0,255)"&gt;break&lt;/span&gt;;
                    }
                }
            }
            &lt;span style="color:rgb(0,0,255)"&gt;foreach&lt;/span&gt; ( &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt; leaf &lt;span style="color:rgb(0,0,255)"&gt;in&lt;/span&gt; ChildLeaves )
            {
                leaf.Distribute();
            }
        }
    }&lt;/pre&gt;
&lt;p&gt;Anyway, first the method checks to see if the number of objects the current leaf contains is more than the maximum allows. If it is, then we need to split this leaf by calling our Split() method. Next we loop through every item in the scene backwards. We do this because later we may call containedObjects.Remove() and we would end up trying access objects that are don't exist at the end of the list, and we would also skip the object after the one we remove. Going backwards through the list with a manual for loop avoids this.
&lt;p&gt;Then for each child leaf of the current one we check to see if the BoundingBox of only that leaf intersects the BoundingBox of the current object. If it does, then we add it to the ContainedObjects list of that leaf and remove it from the list of the current leaf. Then we break from the foreach loop since we've found a leaf that contains the object. Objects that intersect more than one child leaf will not be passed on to the children and instead stay in the current leaf so that we don't get any popping of visibility at the edges of the screen. Finally, we loop through every child leaf and call its Distribute() method.
&lt;p&gt;Now, we finally have our objects distributed throughout our scene. Now, we need some way to figure out how to determine whether the current leaf in within our view frustum. Well fortunately for us this is very simple code thanks to the efforts of the XNA team! We're going to use a nifty little class named BoundingFrustum.
&lt;p&gt;BoundingFrustum represents quite simply a frustum! Best yet, we can create one that represents the view frustum of our camera simply by passing the product of the view and projection matrices as follows:&lt;pre&gt;&lt;span style="color:rgb(0,128,128)"&gt;BoundingFrustum&lt;/span&gt; boundingFrustum = &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingFrustum&lt;/span&gt;( View * Projection );&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;I've created a Camera class with a property named BoundingFrustum that returns this very value. Keep in mind that boundingFrustum needs to get updated whenever either the view or project matrices change.
&lt;p&gt;Now, here's our method that determines draws our visible objects recursively:&lt;pre&gt;&lt;span style="color:rgb(0,0,255)"&gt;    public&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;void&lt;/span&gt; DrawVisible( &lt;span style="color:rgb(0,128,128)"&gt;GameTime&lt;/span&gt; gameTime, &lt;span style="color:rgb(0,128,128)"&gt;BoundingFrustum&lt;/span&gt; boundingFrustum )
    {
        &lt;span style="color:rgb(0,0,255)"&gt;foreach&lt;/span&gt; ( &lt;span style="color:rgb(0,128,128)"&gt;SceneObject &lt;/span&gt;item &lt;span style="color:rgb(0,0,255)"&gt;in&lt;/span&gt; containedObjects )
        {
            item.Draw( gameTime );
        }
        &lt;span style="color:rgb(0,0,255)"&gt;foreach&lt;/span&gt; ( &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf&lt;/span&gt; leaf &lt;span style="color:rgb(0,0,255)"&gt;in&lt;/span&gt; ChildLeaves )
        {
            &lt;span style="color:rgb(0,0,255)"&gt;if&lt;/span&gt; ( leaf.ContainerBox.Intersects( boundingFrustum ) )
                leaf.DrawVisible( gameTime, boundingFrustum );
        }
    }&lt;/pre&gt;
&lt;p&gt;What this method does first is it draws the objects in the current leaf. Then it checks each of the child leaves for intersection with the BroundingFrustum. If it does intersect, meaning that the child leaf is within our sight, we call its DrawVisible() method, otherwise the leaf and thus all its child leaves and all objects contained therein, are not visible to us so they never get drawn.
&lt;p&gt;Finally we have the basic functionality of object distribution and visiblity determination. Now all we have to do is create a Octree class to drive this tree:&lt;pre&gt;&lt;span style="color:rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;Octree&lt;/span&gt; : &lt;span style="color:rgb(0,128,128)"&gt;OctreeLeaf
&lt;/span&gt;{
    &lt;span style="color:rgb(0,0,255)"&gt;public&lt;/span&gt; Octree()
        : &lt;span style="color:rgb(0,0,255)"&gt;base&lt;/span&gt;( &lt;span style="color:rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt;() )
    {
    }

    &lt;span style="color:rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;void&lt;/span&gt; Bounds()
    {
        &lt;span style="color:rgb(0,0,255)"&gt;foreach&lt;/span&gt; ( &lt;span style="color:rgb(0,128,128)"&gt;SceneObject &lt;/span&gt;item &lt;span style="color:rgb(0,0,255)"&gt;in&lt;/span&gt; ContainedObjects)
        {
            ContainerBox = &lt;span style="color:rgb(0,128,128)"&gt;BoundingBox&lt;/span&gt;.CreateMerged( ContainerBox, item.BoundingBox );
        }
    }

    &lt;span style="color:rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;void&lt;/span&gt; Distribute( &lt;span style="color:rgb(0,0,255)"&gt;ref&lt;/span&gt; &lt;span style="color:rgb(0,128,128)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:rgb(0,128,128)"&gt;SceneObject&lt;/span&gt;&amp;gt; scene )
    {&lt;br&gt;        ContainedObjects = scene;
        Bounds();
        &lt;span style="color:rgb(0,0,255)"&gt;base&lt;/span&gt;.Distribute();
    }

    &lt;span style="color:rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0,0,255)"&gt;void&lt;/span&gt; DrawVisible( &lt;span style="color:rgb(0,128,128)"&gt;GameTime&lt;/span&gt; gameTime, &lt;span style="color:rgb(0,128,128)"&gt;Camera&lt;/span&gt; camera )
    {  &lt;br&gt;&lt;span style="color:rgb(0,0,255)"&gt;        base&lt;/span&gt;.DrawVisible( gameTime, camera.BoundingFrustum );&lt;br&gt;    }
}&lt;/pre&gt;
&lt;p&gt;Pretty simple, huh? This derives from OctreeLeaf, because it is basically the root node of the tree, but we need some extra functionality in it.
&lt;p&gt;Lets look at the Bounds method. This method takes every object that the root node (Octree class) contains and uses BoundingBox.CreateMerged() to resize the current ContainerBox to include the BoundingBox of each object. What this does is define the initial size that our root BoundingBox needs to be in order to contain the entire scene.
&lt;p&gt;Next the Distribute method. Note this method overloads not overrides the Distribute method. This is because we need to pass our scene into the method. We then assign scene to ContainedObjects. Then we call Bounds and finally the base class OctreeLeaf's Distribute method. This sets into action the recursive distribution of our scene we set up earlier. 
&lt;p&gt;Finally we have the DrawVisible method, another overload because we need to pass the current Camera. Then we call the base class's DrawVisible method and pass the camera's BoundingFrustum.
&lt;p&gt;That's pretty much it to a relatively simple implementation of an octree. It is optimized for a scene with static objects at the moment and has no support for adding objects. I will probably be adding support in the future, but for the sake of this tutorial, we have the basic functionality we sought.
&lt;p&gt;Hopefully you learned a little more about XNA through this tutorial as I did coding it. I would love to hear your comments, so please feel free to post them!&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+XNA+Octree+Tutorial&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!129.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!129.entry</guid><pubDate>Thu, 12 Apr 2007 22:31:42 GMT</pubDate><slash:comments>2</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!129/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!129.entry#comment</wfw:comment><dcterms:modified>2007-04-13T01:06:37Z</dcterms:modified></item><item><title>Update</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!127.entry</link><description>Ok, so its been a while since I've posted anything, but thats because I've been hard at work, here's a quick list of what I've done:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Implemented Octree functionality.&lt;li&gt;Begun implementing skinning.&lt;li&gt;Added multiple viewport functionality which dynamically adds/remove and resizes viewports accordingly. This is in preparation for a possible port to the 360 environment in the future. Probably do some fancy transition for this if it ever happens.&lt;li&gt;Recoded Keyboard input. Someone previously mentioned that my Keyboard system was a bit overkill, after some more research I had to agree so now I have a much more simplified version that works better for things such as GUI input where I need to grab a whole sequence of keystrokes.&lt;li&gt;Recoded Mouse input. Previous unshown, but also an even driven component. It supports the usual three button mouse with press/release, scrollwheel, and drag events.&lt;li&gt;Working on an in-game editor. Mostly this is waiting on me either designing a GUI or choosing one from the community.&lt;br&gt;&lt;li&gt;Finally, begun creating content for the game itself and getting down into some of the gameplay types.&lt;br&gt;&lt;/ul&gt;I have a few more ideas for mini-tutorials that I may post here. Some are just quick code snippets, but others are a bit more detailed. Leave some comments to encourage me &lt;img src="http://shared.live.com/VIf!VWmJbs6tK-ObyYk28Q/emoticons/smile_wink.gif"&gt;&lt;br&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+Update&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!127.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!127.entry</guid><pubDate>Thu, 12 Apr 2007 01:45:52 GMT</pubDate><slash:comments>1</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!127/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!127.entry#comment</wfw:comment><dcterms:modified>2007-04-16T03:02:27Z</dcterms:modified></item><item><title>No More Scenegraph</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!126.entry</link><description>&lt;p&gt;As I mention &lt;a href="http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!118.entry"&gt;previously&lt;/a&gt;, I decided to change my game engine over to a non-scenegraph scene implementation. Now, mostly the reason we would want to preserve scenegraph functionality is to have the ability to easily parent objects for pivot point or whatnot. However, we can still retain this functionality, with even greater flexibility and extendable. &lt;p&gt;The implementation I have now is basically a SceneManager DrawableGameComponent that has a List&amp;lt;&amp;gt; of SceneItems in the scene. Each SceneItem is passed a reference to this manager so that it can access other items in the scene. For SceneItem I've gone ahead and defined properties that return the Scale, Rotation, Translation, and concatenated Local Matrix. I've also defined one that returns a reference to the SceneManager so that we can access this and thus access other SceneItem if we have a reference to an item. &lt;p&gt;Now we have the basis of scene items being able to access each other and grab whatever Matrix they need. Now what needs to be implemented is a way of creating a relationship such as parenting. What I've done is created an interface that we will implement in each of our relationship classes (from here on I will refer to these relationships as &amp;quot;constraints&amp;quot;):&lt;pre&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;interface I&lt;/span&gt;&lt;span style="color:rgb(0, 128, 128)"&gt;Constraint&lt;br&gt;&lt;/span&gt;{&lt;br&gt;    &lt;span style="color:rgb(0, 0, 255)"&gt;public virtual&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;void&lt;/span&gt; Evaluate( &lt;span style="color:rgb(0, 128, 128)"&gt;Transform&lt;/span&gt; currentItem, &lt;span style="color:rgb(0, 128, 128)"&gt;GameTime&lt;/span&gt; gameTime );&lt;br&gt;}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The overridable method we see here that we will need to implement passes a reference to the item that is going to be parented, and the current GameTime, just in case we ever need it. So now what we do is add some code to our SceneItem class to support the IConstraint system of relationships:
&lt;p&gt;First, we add some members:&lt;pre&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;protected&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:rgb(0, 128, 128)"&gt;IConstraint&lt;/span&gt;&amp;gt; _constraints = &lt;span style="color:rgb(0, 0, 255)"&gt;null&lt;/span&gt;;&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;protected&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;bool&lt;/span&gt; _constraintUpdated = &lt;span style="color:rgb(0, 0, 255)"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The List&amp;lt;&amp;gt; is fairly self-explanatory, its just a list of all the constraints this object has on it and the bool value makes sure that we only call our UpdateConstraints method once as seen below, in case we have a long chain of objects that are constrained: &lt;pre&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;virtual&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;void&lt;/span&gt; UpdateConstraints( &lt;span style="color:rgb(0, 128, 128)"&gt;GameTime&lt;/span&gt; gameTime )&lt;br&gt;{&lt;br&gt;    &lt;span style="color:rgb(0, 0, 255)"&gt;if&lt;/span&gt; ( !_constraintUpdated )&lt;br&gt;    {&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;foreach&lt;/span&gt; ( &lt;span style="color:rgb(0, 128, 128)"&gt;IConstraint&lt;/span&gt; constraint &lt;span style="color:rgb(0, 0, 255)"&gt;in&lt;/span&gt; _constraints )&lt;br&gt;        {&lt;br&gt;            constraint.Evaluate( &lt;span style="color:rgb(0, 0, 255)"&gt;this&lt;/span&gt; );&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        _constraintUpdated = &lt;span style="color:rgb(0, 0, 255)"&gt;true&lt;/span&gt;;&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Now, this is one very important thing to note: UpdateConstraints should only be called after the local matrix has been computed for every item in the scene, which in my case I do in a plain old void Update(GameTime) method. The reason for this is that we need to make sure that if one object is parented to another object and that second object has been rotated, we want to make sure the rotation has been applied before we concatenate matrices.
&lt;p&gt;Finally we get to code our first constraint class. First we derive from Constraint and implement the Evaulate method. The way we implement for a parent constraint would be as follows:
&lt;p&gt; &lt;pre&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;class&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;ParentConstraint&lt;/span&gt; : &lt;span style="color:rgb(0, 128, 128)"&gt;IConstraint&lt;br&gt;&lt;/span&gt;{&lt;span style="color:rgb(0, 0, 255)"&gt;
&lt;/span&gt;    &lt;span style="color:rgb(0, 0, 255)"&gt;private&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;int&lt;/span&gt; _parentIndex = -1;&lt;br&gt;    &lt;span style="color:rgb(0, 0, 255)"&gt;private&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;float&lt;/span&gt; _weight = 1F;&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;
&lt;/span&gt;    &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;void&lt;/span&gt; Evaluate( &lt;span style="color:rgb(0, 128, 128)"&gt;Transform&lt;/span&gt; currentItem, &lt;span style="color:rgb(0, 128, 128)"&gt;GameTime&lt;/span&gt; gameTime )&lt;br&gt;    {&lt;br&gt;        currentItem.SceneManager.Scene[_parentIndex].UpdateConstraints( gameTime );&lt;br&gt;&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;if&lt;/span&gt; ( _parentIndex != -1 )&lt;br&gt;            currentItem.LocalMatrix *= currentItem.SceneManager.Scene[_parentIndex].LocalMatrix * _weight;&lt;br&gt;    }&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;
&lt;p&gt;Yup, that's it. What we're doing here is storing an index for the item we will parent to and a weight that determines how much we will apply the parenting. That's right, we can now ease in and out of parenting by simply ramping up or down the _weight value! See how this is much more flexible than what a ordinary scenegraph would have allowed us to do? Now, we have to make sure that we call the UpdateConstraints method of the item we're parented to before we do anything because if we don't, our first item may be positioned incorrectly as objects further up the chain may not have been updated yet.
&lt;p&gt;I hope that this has inspired some people to move away from the mess of scenegraphs and explore alternate avenues of storing scene data ingame.
&lt;p&gt;Further extensions to this constraint system you could do:
&lt;ul&gt;
&lt;li&gt;Customized parent constraint where scales do not proliferate down a chain of parented objects. 
&lt;li&gt;Parent constraint with multiple parents weighted differently to position our parented object between them. 
&lt;li&gt;Rotation constraint where only the orientations of the objects are shared. 
&lt;li&gt;Snapping constraint where, instead of concatenating the position matrix you assign it instead to make an object snap to the origin of another object, ignoring its own local matrix.&lt;/ul&gt;
&lt;p&gt;There's probably much more that you could do with this system and I'd love to hear from you if you&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+No+More+Scenegraph&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!126.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!126.entry</guid><pubDate>Wed, 21 Mar 2007 18:05:30 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!126/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!126.entry#comment</wfw:comment><dcterms:modified>2007-04-16T03:02:37Z</dcterms:modified></item><item><title>Updates</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!124.entry</link><description>&lt;p&gt;First off I updated the code in my last blog. The functionality hasn't changed, but I've changed it to a static class so that its easier to access instead of a GameComponent/Service. &lt;p&gt;Second, I've changed the theme on the blog so the code should be easier to read now. :)&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+Updates&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!124.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!124.entry</guid><pubDate>Sun, 18 Mar 2007 06:50:02 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!124/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!124.entry#comment</wfw:comment><dcterms:modified>2007-03-18T06:50:02Z</dcterms:modified></item><item><title>Eureka! Keyboard Input!</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!123.entry</link><description>&lt;p&gt; &lt;h6&gt;&lt;/h6&gt; &lt;p&gt;I just finished rewriting my keyboard input component after I had a sudden epiphany while coding my game state code.  &lt;p&gt;Basically, what I had been working on achieving was a way to have events fire for a single key press so that classes throughout my game could create event handlers and handle only the specific key press or key release that they were interested in. This seems like a long way to go just for getting some input when I could have just used Keyboard.GetState();, but the advantage I see is that I only need to check once to see if a certain key has been pressed or released and then my code will call every event handler that has been assigned to that event. Plus it has the advantage of keeping my input logic completely separate from the rest of my game logic.  &lt;p&gt;Now someone may ask &amp;quot;isn't that going to be more trouble if you have to check for multiple keys?&amp;quot; The answer to that is an emphatic yes, which is why I've exposed the current KeyboardState with a property. However, most of the time I personally am going to be checking only one key, such as &amp;quot;is the player hitting the 'W' key so I can move the player forward?&amp;quot;  &lt;p&gt;So, basically what I finally figured out what to do was create a class called KeyEvents that contained keydown and keyup event and matching methods to fire those events and then create an Dictionary&amp;lt;Keys, KeyEvents&amp;gt;. Looking back on this its so simple I don't know why I didn't see it to begin with, probably the 20 hour days I've been spending with XNA this last week. &lt;p&gt;Edit: I've updated the code to make this a static class, since its simple and it won't bother the game much to have an instance automatically created when the program loads.&lt;pre&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;#region&lt;/span&gt; License&lt;br&gt;&lt;br&gt;&lt;span style="color:rgb(0, 128, 0)"&gt;/*&lt;br&gt; * File: KeyboardInput.cs&lt;br&gt; * &lt;br&gt; * Copyright (C)2007 Nathan Levesque (http://rhysyngsun.spaces.live.com)&lt;br&gt; * &lt;br&gt; * This file is supplied freely for use in commercial or non-commercial software&lt;br&gt; * but without any warranty as to its use. By using this software you hold the &lt;br&gt; * copyright owner free of any damages results from such use.&lt;br&gt; * &lt;br&gt; * You are free to modify and distribute this file as you see fit, provided &lt;br&gt; * this license is not removed.&lt;br&gt; * &lt;br&gt; */&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;#endregion&lt;br&gt;&lt;br&gt;#region&lt;/span&gt; Using Statements&lt;br&gt;&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;using&lt;/span&gt; System;&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br&gt;&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;using&lt;/span&gt; Microsoft.Xna.Framework.Input;&lt;br&gt;&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;#endregion&lt;br&gt;&lt;br&gt;namespace&lt;/span&gt; AuroraEngine.Input&lt;br&gt;{&lt;br&gt;    &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;delegate&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;void&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;KeyChange&lt;/span&gt;();&lt;br&gt;&lt;br&gt;    &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;class&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;KeyEvents&lt;br&gt;&lt;/span&gt;    {&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;        #region&lt;/span&gt; Events&lt;br&gt;&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;event&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;KeyChange&lt;/span&gt; OnKeyDown;&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;event&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;KeyChange&lt;/span&gt; OnKeyUp;&lt;br&gt;&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;        #endregion&lt;br&gt;&lt;br&gt;        #region&lt;/span&gt; Methods&lt;br&gt;&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;void&lt;/span&gt; KeyDown()&lt;br&gt;        {&lt;br&gt;            &lt;span style="color:rgb(0, 0, 255)"&gt;if&lt;/span&gt; ( OnKeyDown != &lt;span style="color:rgb(0, 0, 255)"&gt;null&lt;/span&gt; )&lt;br&gt;                OnKeyDown();&lt;br&gt;        }&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;void&lt;/span&gt; KeyUp()&lt;br&gt;        {&lt;br&gt;            &lt;span style="color:rgb(0, 0, 255)"&gt;if&lt;/span&gt; ( OnKeyUp != &lt;span style="color:rgb(0, 0, 255)"&gt;null&lt;/span&gt; )&lt;br&gt;                OnKeyUp();&lt;br&gt;        }&lt;br&gt;&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;        #endregion&lt;br&gt;&lt;/span&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;static&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;class&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;KeyboardInput&lt;br&gt;&lt;/span&gt;    {&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;        #region&lt;/span&gt; Members&lt;br&gt;&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;private&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;static&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:rgb(0, 128, 128)"&gt;Keys&lt;/span&gt;, &lt;span style="color:rgb(0, 128, 128)"&gt;KeyEvents&lt;/span&gt;&amp;gt; keyEventDictionary = &lt;span style="color:rgb(0, 0, 255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:rgb(0, 128, 128)"&gt;Keys&lt;/span&gt;, &lt;span style="color:rgb(0, 128, 128)"&gt;KeyEvents&lt;/span&gt;&amp;gt;();&lt;br&gt;&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;private&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;static&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;KeyboardState&lt;/span&gt; currentState = &lt;span style="color:rgb(0, 0, 255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;KeyboardState&lt;/span&gt;();&lt;br&gt;&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;        #endregion&lt;br&gt;&lt;br&gt;        #region&lt;/span&gt; Methods&lt;br&gt;&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;static&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;void&lt;/span&gt; ConfirmKey( &lt;span style="color:rgb(0, 128, 128)"&gt;Keys&lt;/span&gt; key )&lt;br&gt;        {&lt;br&gt;            &lt;span style="color:rgb(0, 0, 255)"&gt;if&lt;/span&gt; ( !keyEventDictionary.ContainsKey( key ) )&lt;br&gt;                keyEventDictionary.Add( key, &lt;span style="color:rgb(0, 0, 255)"&gt;new&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;KeyEvents&lt;/span&gt;() );&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;static&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;void&lt;/span&gt; Update()&lt;br&gt;        {&lt;br&gt;            &lt;span style="color:rgb(0, 128, 128)"&gt;KeyboardState&lt;/span&gt; previousState = currentState;&lt;br&gt;            currentState = &lt;span style="color:rgb(0, 128, 128)"&gt;Keyboard&lt;/span&gt;.GetState();&lt;br&gt;&lt;br&gt;            &lt;span style="color:rgb(0, 0, 255)"&gt;if&lt;/span&gt; ( currentState == previousState )&lt;br&gt;                &lt;span style="color:rgb(0, 0, 255)"&gt;return&lt;/span&gt;;&lt;br&gt;&lt;br&gt;            &lt;span style="color:rgb(0, 0, 255)"&gt;foreach&lt;/span&gt;(&lt;span style="color:rgb(0, 128, 128)"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color:rgb(0, 128, 128)"&gt;Keys&lt;/span&gt;, &lt;span style="color:rgb(0, 128, 128)"&gt;KeyEvents&lt;/span&gt;&amp;gt; key &lt;span style="color:rgb(0, 0, 255)"&gt;in&lt;/span&gt; keyEventDictionary)&lt;br&gt;            {&lt;br&gt;                &lt;span style="color:rgb(0, 0, 255)"&gt;if&lt;/span&gt; ( previousState.IsKeyDown( key.Key ) &amp;amp;&amp;amp; currentState.IsKeyUp( key.Key ) )&lt;br&gt;                    key.Value.KeyUp();&lt;br&gt;                &lt;span style="color:rgb(0, 0, 255)"&gt;else&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;if&lt;/span&gt; ( previousState.IsKeyUp( key.Key ) &amp;amp;&amp;amp; currentState.IsKeyDown( key.Key ) )&lt;br&gt;                    key.Value.KeyDown();&lt;br&gt;            }&lt;br&gt;        }&lt;br&gt;&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;        #endregion&lt;br&gt;&lt;br&gt;        #region&lt;/span&gt; Properties&lt;br&gt;&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;static&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:rgb(0, 128, 128)"&gt;Keys&lt;/span&gt;, &lt;span style="color:rgb(0, 128, 128)"&gt;KeyEvents&lt;/span&gt;&amp;gt; KeyEventDictionary&lt;br&gt;        {&lt;br&gt;            &lt;span style="color:rgb(0, 0, 255)"&gt;get&lt;/span&gt; { &lt;span style="color:rgb(0, 0, 255)"&gt;return&lt;/span&gt; keyEventDictionary; }&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        &lt;span style="color:rgb(0, 0, 255)"&gt;public&lt;/span&gt; &lt;span style="color:rgb(0, 0, 255)"&gt;static&lt;/span&gt; &lt;span style="color:rgb(0, 128, 128)"&gt;KeyboardState&lt;/span&gt; CurrentState&lt;br&gt;        { &lt;br&gt;            &lt;span style="color:rgb(0, 0, 255)"&gt;get&lt;/span&gt; { &lt;span style="color:rgb(0, 0, 255)"&gt;return&lt;/span&gt; currentState; }&lt;br&gt;        }&lt;br&gt;&lt;br&gt;&lt;span style="color:rgb(0, 0, 255)"&gt;        #endregion&lt;br&gt;&lt;/span&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+Eureka!+Keyboard+Input!&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!123.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!123.entry</guid><pubDate>Sat, 17 Mar 2007 07:01:17 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!123/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!123.entry#comment</wfw:comment><dcterms:modified>2007-04-16T03:02:46Z</dcterms:modified></item><item><title>Update</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!118.entry</link><description>So I've been coding pretty hard the last week or so while I'm on spring break. So far I've managed to code:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Event driven mouse component that includes drag events - some of the code is a bit clumsy and will likely result in a third rewrite. The clumsiness is mostly related to code that is designed to keep the SpriteBatch cursor within the client area, but this code will most likely be moved into the GUI component&lt;br&gt;&lt;li&gt;Event driven keyboard component - this component is not quite how I want it at the moment, its terribly inefficient and I'm looking into finding some other way of implementing it&lt;li&gt;A basic scene manager - I'd originally begun implementing a scene graph, as this was what I'd learned was the way to do things, but after reading &lt;a href="http://home.comcast.net/~tom_forsyth/blog.wiki.html#[[Scene Graphs - just say no]]"&gt;TomF's Blog on saying no to scene graphs&lt;/a&gt; I decided to go with a much simpler approach of using a Dictionary&amp;lt;string, SceneObject&amp;gt; collection to hold all my scene data. Each SceneObject will hold a reference to the SceneManager object so that they can access other objects in the scene by name through the Dictionary collection. I hope to implement a scripting language into the game which should dramatically increase the level of variability in gameplay. I'm looking at &lt;a href="http://lua.org"&gt;Lua&lt;/a&gt;, but also considering rolling my own if I have the time.&lt;br&gt;&lt;li&gt;A basis for a GUI component - incredibly simple right now, but this will more or less get developed as I need it&lt;li&gt;I've also taken the liberty of moving the main engine code into its own class library, I may even further branch off the individual components into their own libraries for the sake of modularity.&lt;/ul&gt;Remaining items I have until I can have a working demo:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Create a function level editor&lt;li&gt;Code a custom Content Processor to import my levels&lt;/ul&gt;So it probably going to be 2-3 weeks before those two things happen since I'll be back at school and extremely busy the second week. Here's to finding more free time! &lt;img src="http://shared.live.com/VIf!VWmJbs6tK-ObyYk28Q/emoticons/smile_regular.gif"&gt;&lt;br&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+Update&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!118.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!118.entry</guid><pubDate>Fri, 16 Mar 2007 06:50:20 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!118/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!118.entry#comment</wfw:comment><dcterms:modified>2007-03-16T06:50:20Z</dcterms:modified></item><item><title>Welcome!</title><link>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!112.entry</link><description>Greetings! I've started this blog as a place to showcase my work on my XNA game that I'm developing for the &lt;a href="http://dreambuildplay.com"&gt;Dream Build Play&lt;/a&gt; Competition. The game is a multiplayer third person shooter game. I'll make some of the game features more readily apparent as time progresses (especially once it gets close to the competition deadline).&lt;br&gt;&lt;br&gt;For the time being I will be posting occasional screen captures, possibly videos, and share some of my code.&lt;br&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-306981137987202659&amp;page=RSS%3a+Welcome!&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=rhysyngsun.spaces.live.com&amp;amp;GT1=rhysyngsun"&gt;</description><comments>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!112.entry#comment</comments><guid isPermaLink="true">http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!112.entry</guid><pubDate>Fri, 09 Mar 2007 22:58:29 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://rhysyngsun.spaces.live.com/blog/cns!FBBD62480D87119D!112/comments/feed.rss</wfw:commentRss><wfw:comment>http://rhysyngsun.spaces.live.com/Blog/cns!FBBD62480D87119D!112.entry#comment</wfw:comment><dcterms:modified>2007-04-12T01:48:53Z</dcterms:modified></item></channel></rss>