<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Monstersoft</title>
	<atom:link href="http://www.monstersoft.com/wp/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.monstersoft.com/wp</link>
	<description>Programming, Physics, Philosophy</description>
	<lastBuildDate>Sun, 05 May 2013 06:42:12 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Eye Sees You</title>
		<link>http://www.monstersoft.com/wp/?p=546</link>
		<comments>http://www.monstersoft.com/wp/?p=546#comments</comments>
		<pubDate>Wed, 17 Aug 2011 05:34:44 +0000</pubDate>
		<dc:creator>flameshadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Axis align]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Eyeballs]]></category>
		<category><![CDATA[Matrix.CreateLookAt]]></category>
		<category><![CDATA[Mouse]]></category>
		<category><![CDATA[Viewport.Unproject]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://www.monstersoft.com/wp/?p=546</guid>
		<description><![CDATA[Recently I&#8217;ve been sidetracked with a project (which I will go into more detail about later). That project was sidetracked briefly to answer the question: how does one orient a 3D model to point at something? You might need to &#8230;<p class="read-more"><a href="http://www.monstersoft.com/wp/?p=546">Continue reading</a></p>]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignleft" style="width: 190px"><a href="http://www.monstersoft.com/wp/?p=546"><img src="http://www.monstersoft.com/images/MSLogo3DSmall.png" alt="MS Logo in 3D" width="180" height="95" /></a><p class="wp-caption-text">Eye Sees You</p></div>
<p>Recently I&#8217;ve been sidetracked with a project (which I will go into more detail about later). That project was sidetracked briefly to answer the question: how does one orient a 3D model to point at something? You might need to use this should you want to point a ship at a specific star, or have a moon tidally locked to its planet so that one side of the moon is always facing it. For my case specifically, it was how to orient eyes on a model to track the mouse. It has a deceptively simple premise, but a non-obvious answer.</p>
<p><span id="more-546"></span></p>
<h2>[World]</h2>
<p>By now, if you&#8217;ve read any <a href="http://rbwhitaker.wikidot.com/basic-matrices">3d tutorials</a> on the Internet, you&#8217;re familiar with the world/view/projection matrices. A model in model-space has its coordinates run through a series of transforms which first is moved to world space, then modified to be what the camera sees, then projected onto the screen. The only matrix we need to worry about changing is the world matrix, although all three are eventually used to make this work.</p>
<h2>[Eye Spy Axis Angles: X-eYe-Zed]</h2>
<p>When I first approached this problem, I assumed it was a simple matter of rotation. Basically one should be able to work out the angle difference between the object&#8217;s forward face and the point to look at, and then you rotate around the relevant axes.</p>
<div class="wp-caption alignright" style="width: 210px"><a href="http://www.fundza.com/mel/axis_to_vector/align_axis_to_vector.html"><img src="http://www.monstersoft.com/images/axis_angles.gif" alt="Axis Angles between two 3-dimensional coordinates" width="200" height="219" /></a><p class="wp-caption-text">Axis Angles between two 3-dimensional coordinates</p></div>
<p>My first attempt at working this out involved using the <a href="http://en.wikipedia.org/wiki/Atan2">atan2</a> <a href="http://msdn.microsoft.com/en-us/library/system.math.atan2.aspx">method</a> to figure out the angles for two of the axes. The atan2 function will compute the angle in radians between the positive x-axis of a plane and the point given by the coordinates (x, y) on it. I figured that you could compute the angle difference in the X-Y plane, and the angle difference in the Y-Z plane those would give you the amount of rotation required to orient your model.</p>
<div class="wp-caption alignleft" style="width: 210px"><a href="http://www.fundza.com/mel/axis_to_vector/align_axis_to_vector.html"><img class=" " src="http://www.monstersoft.com/images/z_rotation.png" alt="Rotation around the Z axis" width="200" height="219" /></a><p class="wp-caption-text">Why using atan2 only on each plane individually doesn&#039;t work</p></div>
<p>It turns out that you cannot compute them individually, and the figure on the left demonstrates why. You can work out the angle in one axis, but then you <em>also</em> need to rotate the coordinates before working out the second angle.</p>
<p>Once you do have the proper angles, you can either create a series of rotations using Matrix.CreateRotationX/Y, or you can use Matrix.CreateFromYawPitchRoll. There are example of how to do both in the sample source code provided (see below).</p>
<p>There&#8217;s also a third solution available, which is to use an inverted Matrix.CreateLookAt. The pertinent information came from a <a title="LookAt view matrix is an inverted world matrix" href="http://www.gamedev.net/topic/539045-xna-matrixcreatelookat-not-behaving-as-expected-when-changing-the-up-vector/" target="_blank">post on gamedev.net by MJP</a>:</p>
<blockquote><p>&#8220;&#8230;but a view matrix is just the inverse of a &#8220;world&#8221; transformation. If you think about it makes sense: a world matrix takes something and transforms it from its local space to it&#8217;s actual world position and orientation. A view matrix takes things that are in their world position and orientation, and transforms them to a coordinate space local to the camera.&#8221;</p></blockquote>
<h2>[Where Am Eye?]</h2>
<p>A mouse cursor on the screen, by definition, exists solely on a plane in the projected scene. Which plane you want it to exist in depends on many factors, including your camera&#8217;s field of view, your aspect ratio, near/far plane distance, et al. One of the problems I encountered early on was that my model just didn&#8217;t appear to be looking at the mouse cursor. To figure out what was going wrong, I wrote a very simple program to reduce all possible variables involved in orientation. It&#8217;s an eyeball model at (0,0,0) set to point at the mouse. When trying to figure out what the Z value should be, I got wild variations on orientation. For example:</p>
<div class="wp-caption aligncenter" style="width: 610px"><img class="  " src="http://www.monstersoft.com/images/EyeZ0.0.png" alt="Mouse Z = 0" width="600" height="300" /><p class="wp-caption-text">Eye pointing at mouse in lower left corner with Z = 0. Doesn&#039;t look right.</p></div>
<div class="wp-caption aligncenter" style="width: 610px"><img class=" " src="http://www.monstersoft.com/images/EyeZ0.5.png" alt="Mouse Z = 0.5" width="600" height="300" /><p class="wp-caption-text">Eye pointing at mouse in lower left corner with Z = 0.5. Looks better, but still not quite right.</p></div>
<div class="wp-caption aligncenter" style="width: 610px"><img src="http://www.monstersoft.com/images/EyeZ0.8.png" alt="Mouse Z = 0.8" width="600" height="300" /><p class="wp-caption-text">Eye pointing at mouse in lower left corner with Z = 0.8. Looks pretty good.</p></div>
<div class="wp-caption aligncenter" style="width: 610px"><img class=" " src="http://www.monstersoft.com/images/EyeZ1.0.png" alt="Mouse Z = 1.0" width="600" height="300" /><p class="wp-caption-text">Eye pointing at mouse in lower left corner with Z = 1. Too much? Sometimes more isn&#039;t better.</p></div>
<p>By placing the mouse at Z = 0.8, it &#8220;looks&#8221; realistic. Choosing a proper Z value only matters if you&#8217;re orienting something towards the mouse. If you&#8217;re doing <a title="3D Mouse Picking" href="http://www.enchantedage.com/xna-picking" target="_blank">mouse picking in 3d</a> then you&#8217;ll just cast a ray from the near plane to the far plane.</p>
<h2>[But There Aren't Any Bones In An Eyeball]</h2>
<p>Before this project I had never attempted to load a model with XNA and seriously do anything with it. So, in attempting to do something so simple I ended up learning a great deal. First, though, a little about the model.</p>
<div class="wp-caption alignright" style="width: 410px"><a href="http://www.monstersoft.com/images/MSLogoEarlyAttempt-Full.png"><img class="  " src="http://www.monstersoft.com/images/MSLogoEarlyAttempt.png" alt="MS Logo Early Attempt" width="400" height="374" /></a><p class="wp-caption-text">Early attempt at eye tracking. I unprojected the mouse based on a world matrix that didn&#039;t take into account the bone transform of each eye.</p></div>
<p>The model consists of 7 pieces: the mesh for the M; left/right eyeballs; and upper/lower eyelids for each eye. The FBX format allows you retain the names of individual meshes. So, for example, I have names like EyeballLeft and EyelidRightTop. This allows me to see which mesh I&#8217;m dealing with in the foreach loop one uses to draw a model.</p>
<p>However, unlike the AxisTest demo where the eyeball resides at the origin with no transforms, the eyeballs on the logo are slightly offset. The mouse coordinate needs to be unprojected for each eye using the current world matrix and their absolute bone transform. To get access to that information we have to snag some extra info from the model.</p>
<p>Inside the model is a Matrix[] of transforms, and you can get at this array using <a title="Model.CopyAbsoluteBoneTransformsTo method (msdn)" href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.model.copyabsolutebonetransformsto(v=XNAGameStudio.40).aspx" target="_blank">Model.CopyAbsoluteBoneTransformsTo()</a> which allows access to the matrix representing the location of a specific mesh. It is useful to know this information if, say, you wanted to know where an eyeball was. In the example, I have drawn XYZ orientation of each eyeball based on the center of that eye. To get the actual location, you would use<br />
<em>location = Vector3.Transform(Vector3.Zero, transforms[mesh.ParentBone.Index]);</em><br />
That is, you transform (0,0,0) against the bone matrix of the indexed parent bone and this will give you the relative offset in model coordinates.</p>
<h2>[You're Not Being Helpful. Eye Just Need Code]</h2>
<p>Alright, alright. So there are [at least] four ways to easily construct a matrix to orient a model towards a position in space. If you use them and your mesh doesn&#8217;t orient properly, go reread the above for more information as to why.</p>
<pre name="code" class="c#">public Matrix LookAt(Vector3 position, Vector3 lookAt)
{
    return Matrix.Invert(Matrix.CreateLookAt(position, -lookAt, Vector3.Up));
} // Matrix LookAt()</pre>
<pre name="code" class="c#">public Matrix LookAt2(Vector3 position, Vector3 lookAt)
{
    Matrix rotation;
    Vector3 diff = lookAt - position;
    // Calculate the angle for rotation around the y axis
    float angleY = (float)Math.Atan2(diff.X, diff.Z);
    rotation = Matrix.CreateRotationY(angleY);
    // Calculate new forward vector so that we can
    // construct our own virtual coordinate system
    Vector3 newForward = Vector3.Transform(Vector3.Backward, rotation);
    newForward.Normalize();
    // Calculate rotation around x axis from virtual coordinate system
    float angleX = (float)Math.Atan2(-diff.Y, Vector3.Dot(newForward, diff));
    // Calculate proper rotation matrix
    rotation = Matrix.CreateRotationX(angleX) * Matrix.CreateRotationY(angleY);
    return rotation;
} // Matrix LookAt2()</pre>
<pre name="code" class="c#">public Matrix LookAt3(Vector3 position, Vector3 lookAt)
{
    Matrix rotation;
    Vector3 diff = lookAt - position;
    // Calculate the angle for rotation around the y axis
    float yaw = (float)Math.Atan2(diff.X, diff.Z);
    rotation = Matrix.CreateRotationY(yaw);
    // Calculate new forward vector so that we can
    // construct our own virtual coordinate system
    Vector3 newForward = Vector3.Transform(Vector3.Backward, rotation);
    newForward.Normalize();
    // Calculate rotation around x axis from virtual coordinate system
    float pitch = (float)Math.Atan2(-diff.Y, Vector3.Dot(newForward, diff));
    // Calculate proper rotation matrix
    rotation = Matrix.CreateFromYawPitchRoll(yaw, pitch, 0);
    return rotation;
} // Matrix LookAt3()</pre>
<pre name="code" class="c#">public Matrix LookAt4(Vector3 position, Vector3 lookAt)
{
    Vector3 diff = lookAt - position;
    // Calculate the length of the vector along the X-Z axis
    double xzLength = Math.Sqrt(diff.X * diff.X + diff.Z * diff.Z);
    // Calculate the angle along the y axis
    double yAngle = Math.Acos(diff.Z / xzLength);
    double vecLength = Math.Sqrt(diff.X * diff.X + diff.Y * diff.Y + diff.Z * diff.Z);
    double xAngle = Math.Acos(xzLength / vecLength);

    // Check to see if there is no rotation whatsoever for one axis
    if (xzLength == 0)
    {
        yAngle = (diff.X &gt; 0) ? MathHelper.ToRadians(90) : MathHelper.ToRadians(-90);
    }
    else
    {
        yAngle = Math.Acos(diff.Z / xzLength);
    }

    xAngle = Math.Acos(xzLength / vecLength);

    // Determine which quandrant it actually falls into
    if (diff.Y &gt; 0) xAngle = -xAngle;
    if (diff.X &lt;= 0) yAngle = -yAngle;

    return Matrix.CreateRotationX((float)xAngle)
           * Matrix.CreateRotationY((float)yAngle);
} // Matrix LookAt4()</pre>
<p>All of these assume your model&#8217;s front is +Z.</p>
<p>Many thanks to <a title="Firzen's Homepage" href="http://elenilib.firzen.de/" target="_blank">Firzen</a> for working out the math on the LookAt2() and LookAt3() method. Also, many thanks to <a title="Malcolm Kesson's homepage" href="http://www.fundza.com/index.html" target="_blank">Malcolm Kesson</a> for the LookAt4() method. There are probably other ways to implement this using quanternions, but that will be the subject of another post. All of the above methods can be seen in action in the <a title="Axis Test (359000 bytes)" href="http://www.monstersoft.com/download/AxisTest.zip">AxisTest demo</a>.</p>
<h2>[The Eyes Have It]</h2>
<p>One last note: to actually <a title="Rendering realistic eyes" href="http://www.3dluvr.com/rogueldr/tutorials/eye/eyes.html" target="_blank">render realistic eyeballs</a> is <a title="Andrew Whitehurst's realistic eyeball rendering tutorial" href="http://www.andrew-whitehurst.net/eyeTut.html" target="_blank">relatively complicated</a>. The eyeballs rendered for the M are neither complicated nor accurate. They&#8217;re basically squashed spheres with part of it coloured black. The eyeball used in the AxisTest is one of the ones used in the M logo, but <a title="How to subsurf a mesh in Blender" href="http://wiki.blender.org/index.php/Doc:Manual/Modifiers/Mesh/Subsurf" target="_blank">subsurfed</a>. Unfortunately, this extruded the iris/pupil area and I&#8217;m currently not well enough versed in Blender to fix it.</p>
<h2>[Summary: Eye Puns Result In Terrible Grammar]</h2>
<p><img src="http://www.monstersoft.com/images/MonsterSoft-White.png" alt="MonsterSoft" width="566" height="108" /></p>
<p>To summarize how to make an object track the mouse:</p>
<ol>
<li><a title="Viewport.Unproject (msdn)" href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.viewport.unproject.aspx" target="_blank">unproject</a> the mouse cursor using the view/projection matrices and the world matrix relevant to your frame of reference (including bone transforms if applicable), paying close attention to which plane the mouse is in</li>
<li>adjust that world matrix with another matrix that orients the object to the 3-d coordinate returned by the unprojected mouse<em><br />
</em></li>
<li>???</li>
<li>Profit.</li>
</ol>
<p><span style="font-size: 20px;font-weight: bold">[References]</span></p>
<p><a title="RB Whitaker's Tutorial on Basic Matrices" href="http://rbwhitaker.wikidot.com/basic-matrices" target="_blank">http://rbwhitaker.wikidot.com/basic-matrices</a></p>
<p><a title="Align Axis to Vector" href="http://www.fundza.com/mel/axis_to_vector/align_axis_to_vector.html" target="_blank">http://www.fundza.com/mel/axis_to_vector/align_axis_to_vector.html</a></p>
<p><a title="Inverse Matrix.CreateLookAt (gamedev.net)" href="http://www.gamedev.net/topic/539045-xna-matrixcreatelookat-not-behaving-as-expected-when-changing-the-up-vector/" target="_blank">http://www.gamedev.net/topic/539045-xna-matrixcreatelookat-not-behaving-as-expected-when-changing-the-up-vector/</a></p>
<p><a title="3D Mouse Picking" href="http://www.enchantedage.com/xna-picking" target="_blank">http://www.enchantedage.com/xna-picking</a></p>
<p><a title="Firzen's Homepage" href="http://elenilib.firzen.de/" target="_blank">http://elenilib.firzen.de/</a></p>
<p><a title="Realistic rendering of eyeballs by Adam Baroody" href="http://www.3dluvr.com/rogueldr/tutorials/eye/eyes.html" target="_blank">http://www.3dluvr.com/rogueldr/tutorials/eye/eyes.html</a></p>
<p><a title="Andrew Whitehurst's realistic eyeball rendering tutorial" href="http://www.andrew-whitehurst.net/eyeTut.html" target="_blank">http://www.andrew-whitehurst.net/eyeTut.html</a></p>
<p><a title="How to subsurf a mesh in Blender" href="http://wiki.blender.org/index.php/Doc:Manual/Modifiers/Mesh/Subsurf" target="_blank">http://wiki.blender.org/index.php/Doc:Manual/Modifiers/Mesh/Subsurf</a></p>
<p><a title="Atan2 (wikipedia)" href="http://en.wikipedia.org/wiki/Atan2" target="_blank">http://en.wikipedia.org/wiki/Atan2</a></p>
<p><a title="Math.Atan2 method (msdn)" href="http://msdn.microsoft.com/en-us/library/system.math.atan2.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/system.math.atan2.aspx</a></p>
<p><a title="Model.CopyAbsoluteBoneTransformsTo method (msdn)" href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.model.copyabsolutebonetransformsto(v=XNAGameStudio.40).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.model.copyabsolutebonetransformsto(v=XNAGameStudio.40).aspx</a></p>
<p><a href="http://joestevens.net/xna/alternate-view-matrix-construction/">http://joestevens.net/xna/alternate-view-matrix-construction/</a></p>
<h2>[Downloads]</h2>
<p><a title="http://www.monstersoft.com/download/AxisTest.zip (359000 bytes)" href="http://www.monstersoft.com/download/AxisTest.zip">http://www.monstersoft.com/download/AxisTest.zip</a> (359000 bytes) (C#/XNA 4.0 Source; Public Domain)</p>
<p><a title="Axis Test Demo (39104 bytes) (Binary only) " href="http://www.monstersoft.com/download/AxisTestDemo.zip">http://www.monstersoft.com/download/AxisTestDemo.zip</a> (39104 bytes) (Binary only)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.monstersoft.com/wp/?feed=rss2&#038;p=546</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deleting From A Live Collection</title>
		<link>http://www.monstersoft.com/wp/?p=500</link>
		<comments>http://www.monstersoft.com/wp/?p=500#comments</comments>
		<pubDate>Sat, 02 Jul 2011 01:30:32 +0000</pubDate>
		<dc:creator>flameshadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://www.monstersoft.com/wp/?p=500</guid>
		<description><![CDATA[What happens if you&#8217;re iterating through a collection using a foreach() loop and you decide you want to delete an item? You&#8217;ll get the message &#8220;Collection was modified; enumeration operation may not execute.&#8221;  While there are a variety of ways &#8230;<p class="read-more"><a href="http://www.monstersoft.com/wp/?p=500">Continue reading</a></p>]]></description>
			<content:encoded><![CDATA[<p>What happens if you&#8217;re iterating through a collection using a foreach() loop and you decide you want to delete an item? You&#8217;ll get the message &#8220;Collection was modified; enumeration operation may not execute.&#8221;  While there are a variety of ways to solve this, there&#8217;s one quite elegant solution.<br />
<span id="more-500"></span></p>
<h2>[The Elegant Uni...List]</h2>
<p>A <a title="Zach Fogg's Blog" href="http://blog.zachfogg.com/" target="_blank">fellow denizen</a> in the ##XNA channel on FreeNode had an inquiry involving a foreach() loop and deleting items.</p>
<p>The general idea is that you have a list of items, and some of those items you may want to delete out of the list as you&#8217;re traversing it. You can do this with multiple lists, using a queue where you requeue items, tagging what should be deleted, etc. But none of those are elegant.</p>
<p>So, let&#8217;s say you only want a single list, you don&#8217;t care about the order of the items in said list, and you want to iterate over it exactly once. For all the elements in the list: if you find one you want to delete then you swap it with the &#8220;last&#8221; element, recheck the current index, and decrease the total count of items in the list. Generically it would look like:</p>
<pre>lastIndex &lt;- list.Count
<strong>for</strong> index &lt;- 0 <strong>to</strong> lastIndex
   <strong>do if</strong> list[index] is to be deleted
      <strong>then</strong>
         swap(list[index], list[lastIndex])
         index &lt;- index - 1
         lastIndex &lt;- lastIndex - 1

list &lt;- { list[0] .. list[lastIndex] }</pre>
<p>Voilà.</p>
<h2>[Sample Code]</h2>
<p>Here&#8217;s an example that will check if elements in a List are even, and remove them. Note that the ending order won&#8217;t necessarily be the same as the starting order. Also, this system works for reference types.</p>
<pre name="code" class="c#">using System;
using System.Collections.Generic;

namespace ListDelete
{
    class Program
    {
        static void Main()
        {
            List&lt;int&gt; MyList = new List&lt;int&gt;() { 1, 2, 7, 3, 4, 4, 5, 5, 6, 7 };

            int lastIndex = MyList.Count;
            int index = 0;
            for (index = 0; index &lt; lastIndex; index++)
            {
                if (MyList[index] % 2 == 0)
                {
                    // swap this element with the last element
                    var x = MyList[index];
                    MyList[index] = MyList[lastIndex-1];
                    MyList[lastIndex - 1] = x;

                    // recheck this index
                    --index;

                    // decrease our total number of elements to be worked on
                    --lastIndex;
                } // if
            } // for index

            // remove the elements we no longer wanted
            MyList.RemoveRange(index, MyList.Count - lastIndex);

            // Display the remaining elements in the list
            foreach (var item in MyList)
            {
                Console.WriteLine(item);
            } // foreach

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey(); // Wait for user input to exit
        } // void Main()
    } // class Program
} // namespace</pre>
<p>The output of the above is:</p>
<pre>1
7
7
3
5
5
Press any key to continue...</pre>
<h2>[Links]</h2>
<p><a title="Zach Fogg's Blog" href="http://blog.zachfogg.com/" target="_blank">http://blog.zachfogg.com/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.monstersoft.com/wp/?feed=rss2&#038;p=500</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mouse Traps</title>
		<link>http://www.monstersoft.com/wp/?p=474</link>
		<comments>http://www.monstersoft.com/wp/?p=474#comments</comments>
		<pubDate>Wed, 22 Jun 2011 15:28:03 +0000</pubDate>
		<dc:creator>flameshadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[ClipCursor]]></category>
		<category><![CDATA[Mouse]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://www.monstersoft.com/wp/?p=474</guid>
		<description><![CDATA[Recently there was a discussion in the ##XNA channel on Freenode about how to constrain the mouse to the game-window. The solution proved to be non-obvious and required a little bit of creativity to implement. [The Mouse] Add the following &#8230;<p class="read-more"><a href="http://www.monstersoft.com/wp/?p=474">Continue reading</a></p>]]></description>
			<content:encoded><![CDATA[<p>Recently there was a discussion in the ##XNA channel on Freenode about how to constrain the mouse to the game-window. The solution proved to be non-obvious and required a little bit of creativity to implement.</p>
<p><span id="more-474"></span></p>
<h2>[The Mouse]</h2>
<p>Add the following to your <em>using</em> statements:</p>
<pre name="code" class="c#">using System.Runtime.InteropServices;</pre>
<p>Inside your G<em>ame</em> class, add the following:</p>
<pre name="code" class="c#">[DllImport("user32.dll")]
static extern void ClipCursor(ref Rectangle rect);
[DllImport("user32.dll")]
static extern void ClipCursor(IntPtr rect);</pre>
<p>Add the following code to your game&#8217;s <em>Initialize()</em> method:</p>
<pre name="code" class="c#">this.IsMouseVisible = true;

Rectangle rect = Window.ClientBounds;
rect.Width += rect.X;
rect.Height += rect.Y;

ClipCursor(ref rect);</pre>
<p>Finally, inside your game&#8217;s <em>Update()</em> method add:</p>
<pre name="code" class="c#">if (IsActive)
{
     Rectangle rect = Window.ClientBounds;
     rect.Width += rect.X;
     rect.Height += rect.Y;

     ClipCursor(ref rect);
}</pre>
<h2>[The Trap]</h2>
<p>A few things to note about the above. The <a title="ClipCursor() function (msdn)" href="http://msdn.microsoft.com/en-us/library/ms648383(v=vs.85).aspx" target="_blank">ClipCursor() function</a> expects a pointer to a Rectangle, so we pass in a reference. To allow the cursor to move freely anywhere on the screen again, one has to pass null instead of a rectangle. Since you can&#8217;t pass in a null reference in C#, we have to overload the ClipCursor() function with a second one that allows for a null parameter (IntPtr rect).</p>
<p>ClipCursor() assumes that the rectangle contains the coordinates of the bounding area. Window.ClientBounds contains an XNA/C# style rectangle, which is defined by (X, Y, Width, Height). To get the actual bounding area, one has to adjust the Width/Height with the X/Y.</p>
<p>There is <a title="Discussion About Constraining the Mouse (msdn)" href="http://forums.create.msdn.com/forums/p/3553/18364.aspx" target="_blank">some debate</a> over whether keeping the mouse inside the window border is a good idea or not. Situations where it&#8217;s required are probably pretty rare, but there are some high-profile games that do it (e.g. Minecraft).</p>
<h2>[References]</h2>
<p><a title="Mouse Class (msdn)" href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.mouse.aspx" target="_blank"></a><a title="Mouse Class (msdn)" href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.mouse.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.mouse.aspx</a></p>
<p><a title="ClipCursor() function (msdn)" href="http://msdn.microsoft.com/en-us/library/ms648383(v=vs.85).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/ms648383(v=vs.85).aspx</a></p>
<p><a title="How to prevent the mouse from going out of the window? (msdn)" href="http://forums.create.msdn.com/forums/p/3553/18364.aspx" target="_blank">http://forums.create.msdn.com/forums/p/3553/18364.aspx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.monstersoft.com/wp/?feed=rss2&#038;p=474</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Serialization Benchmarks</title>
		<link>http://www.monstersoft.com/wp/?p=353</link>
		<comments>http://www.monstersoft.com/wp/?p=353#comments</comments>
		<pubDate>Sun, 19 Jun 2011 08:34:56 +0000</pubDate>
		<dc:creator>flameshadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.monstersoft.com/wp/?p=353</guid>
		<description><![CDATA[I had a very nice design and setup ready for my Hextille project when I decided to dabble with serialization. Like the old sweater where you pull on one string only to dislodge another, my design had to change to &#8230;<p class="read-more"><a href="http://www.monstersoft.com/wp/?p=353">Continue reading</a></p>]]></description>
			<content:encoded><![CDATA[<p>I had a very nice design and setup ready for my Hextille project when I decided to dabble with serialization. Like the old sweater where you pull on one string only to dislodge another, my design had to change to allow for serialization. In the end, I just wanted to scream &#8220;Not now, silent singer. Not now!&#8221; Basically what I want to accomplish is to serialize a graph (vertices and edges) including support for cyclic references, generics, child nodes, enumerated types, etc.</p>
<p><span id="more-353"></span>I encountered a fair amount of pain trying to get various forms of serialization working. There&#8217;s a nice long article which may or may not ever see the light of day about that. Regardless, this post is specifically about how fast certain serialization techniques.</p>
<h2>[The Techniques]</h2>
<p>So, what forms of serialization are there? The main ones covered with any depth here will be:</p>
<table border="”1″" cellspacing="”0″" cellpadding="”0″" width="”390″">
<tbody>
<tr>
<td>Type</td>
<td>Description</td>
</tr>
<tr>
<td>[Serializable]</td>
<td>Simplest and easiest implementation. You tag each object with the [Serializable] attribute and let the serializer work it out.</td>
</tr>
<tr>
<td>ISerializable Interface</td>
<td>Adding the ISerializable interface to your class objects lets you have fine-grained control over how things are serialized.</td>
</tr>
<tr>
<td>XML Attribute Serialization</td>
<td>Similar to the [Serializable] attribute, but outputs XML.</td>
</tr>
<tr>
<td>IXmlSerializable Interface</td>
<td>Similar to adding the ISerializable interface to your objects, but allows you to write output via an XML Serializer</td>
</tr>
<tr>
<td>JSON</td>
<td>Similar to XML serialization, except it produces somewhat more readable text with less verbosity.</td>
</tr>
<tr>
<td>Binary</td>
<td>Involves simply dumping members of your object(s) to a binary stream.</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h2>[The Gotchas]</h2>
<p>Here&#8217;s the thing: every form of serialization has <strong>some</strong> form of drawback.</p>
<table border="”1″" cellspacing="”0″" cellpadding="”0″" width="”390″">
<tbody>
<tr>
<td>Type</td>
<td>How it &#8220;Brings The Pain&#8221;</td>
</tr>
<tr>
<td>[Serializable]</td>
<td>Produces files that are a fair bit bigger than one might expect. Isn&#8217;t very fast (see below)</td>
</tr>
<tr>
<td>ISerializable Interface</td>
<td>Implementing the ISerializable Interface on your classes means that you can&#8217;t use the default [Serializable] method. Once you start implementing the interface, it&#8217;s all or nothing. Suffers performance issues (see below).</td>
</tr>
<tr>
<td>XML Serialization</td>
<td>For collections, only works on those which implement ICollection or IEnumerable. That means serialization of Dictionary&lt;&gt; is not possible without a <a title="XML Serializable Dictionary" href="http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx" target="_blank">custom solution</a> (and once you use that solution, things get messy if you want to also use [Serializable]). Suffers massive performance and size issues (see below).</td>
</tr>
<tr>
<td>JSON</td>
<td>JSON produces very nice-looking, readable and compact output, except you can&#8217;t export a dictionary that isn&#8217;t &lt;string, object&gt;.</td>
</tr>
<tr>
<td>Binary</td>
<td>Saving things as binary-only loses all type information and has potential byte-order problems.</td>
</tr>
</tbody>
</table>
<p>There is a more in-depth writeup about <a title="Pros and Cons of Serialization" href="http://www.dotneat.net/2009/03/22/NETSerializationUsingBinaryFormaterSoapFormatterAndXmlSerializer.aspx">the pros and cons of serialization techniques</a> by Iván Loire.</p>
<h2>[It's a Big, Big, Big World Out There]</h2>
<p>When creating a Hextille&lt;&gt; data structure, you pass in a radius which represents how many cells you can go between the origin and the edge of the &#8220;map&#8221;. The formula for determining how many cells there are is as follows:</p>
<p><img class="alignnone" src="http://www.monstersoft.com/images/HextilleSize.png" alt="Sum(R*6)+1" width="85" height="30" /></p>
<p>Each cell (<em>vertex</em>) contains path information (<em>edges) </em>to adjacent cells, including the destination, a cost and whether the path is open. For a Hextille&lt;&gt; with a radius of 1000, you&#8217;re looking at <strong>3003001 vertices</strong> (the center cell is the odd one out) and <strong>18006000 edges</strong>. The benefits (or at least the detriments) of this implementation are moderately clear. On the one hand, since this isn&#8217;t implemented using flat arrays, you need to have some contextual information about your location and the destination location. That adds a little bit of overhead to each cell and each path. On the other hand, you are given the ability to have a true graph structure and quick lookups, not to mention the ability to have a path to non-adjacent nodes. Since I&#8217;m also storing references to adjacent nodes, that creates a situation where memory becomes an issue at about R=1200. One positive aspect of this system is that extensions to the HexNode class don&#8217;t proportionally add much more to the map sizes.</p>
<p>For most potential games using this system, I don&#8217;t foresee needing more than R=100 for any individual map (and maps can be stitched together regardless).</p>
<h2>[I Feel The Need... The Need For Speed]</h2>
<p>So, given the above list of serialization options, how did they fare?</p>
<p>Horribly.</p>
<p>The first thing I did was to try out [Serializable]. The speed was poor, and every subsequent test just produced worse results:</p>
<div class="wp-caption alignnone" style="width: 587px"><a href="http://www.monstersoft.com/images/SerializationSavingTime.png" target="_blank"><img class=" " src="http://www.monstersoft.com/images/SerializationSavingTimeSmall.png" alt="Serialization Saving Time Chart" width="577" height="385" /></a><p class="wp-caption-text">Serialization Saving Time (Click for larger image)</p></div>
<p>The methodology employed was to create a Hextille&lt;&gt; of radius R (0 to 99), save it and then reload it. Since there was some overhead involved in creating the file, and saving a single cell time was so small, I tossed out all the 0-radius times. I used a binary formatter to serialize.</p>
<p>From the above it becomes obvious that the best &#8220;serialization&#8221; technique is to simply use the default [Serializable] attribute tag. For raw speed though, nothing beat simply outputting the data as binary. More on that below. The worst result &#8212; the IXmlSerializable Interface &#8212; took nearly 10 seconds to save a Hextille&lt;&gt; of radius=100. One might be able to get away with that in a map editor, but for anything real-time that just won&#8217;t work.</p>
<p>Loading times produced interesting results:</p>
<div class="wp-caption alignnone" style="width: 587px"><a href="http://www.monstersoft.com/images/SerializationLoadingTime.png" target="_blank"><img class=" " src="http://www.monstersoft.com/images/SerializationLoadingTimeSmall.png" alt="Serialization Loading Time Chart" width="577" height="385" /></a><p class="wp-caption-text">Serialization Loading Time (Click for larger image)</p></div>
<p>&nbsp;</p>
<p>Here, again, we see [Serializable] as the best choice for &#8220;serialization&#8221;. What I found surprising was that the loading times for using either interface method came out about the same. Still, the loading time for a Hextille&lt;&gt; with R=99 took nearly <strong>25 seconds</strong> to load. That&#8217;s simply unacceptable for a game.</p>
<p>However, the BinaryReader was blazingly fast. So fast that I quadruple-checked to ensure it was working properly. Want to know how fast it is? When creating a Hextille&lt;&gt;, the constructor will link the cells together with proper path information, which also contains a reference to the destination node. Obviously you cannot serialize a reference to an object in memory, so that information is lost when saving. To fix this, one has to re-link the references at load time. This re-linking isn&#8217;t included in the timing for [Serializable], ISerializable, or IXmlSerializable. Only the BinaryReader loading technique implemented the re-linking (so I could check it was importing properly). The time above for BinaryReader <strong>includes</strong> the re-linking. It&#8217;s that fast.</p>
<h2>["All Programming Is An Exercise In Caching" -- Terje Mathisen]</h2>
<p>&#8220;Okay&#8221;, I hear you think, &#8220;But what if the data is fitting nicely into the file cache when using the BinaryReader?&#8221; Well, that&#8217;s a good point. Outputting just the binary loses all type information, and everything is nicely aligned and small. What about that?</p>
<div class="wp-caption alignnone" style="width: 587px"><a href="http://www.monstersoft.com/images/BinaryReaderWriterTime.png" target="_blank"><img class="  " src="http://www.monstersoft.com/images/BinaryReaderWriterTimeSmall.png" alt="BinaryReader/Writer Time Chart" width="577" height="385" /></a><p class="wp-caption-text">BinaryReader/Writer Times for Hextille&lt;&gt; Radius = 1 .. 250 (Click for larger image)</p></div>
<p>That&#8217;s obviously not the issue. A Hextille&lt;&gt; with a radius=250 has <strong>188251 vertices</strong> and <strong>1126500 edges</strong> and still it only took about 2.5 seconds to handle.</p>
<h2>[Conclusions]</h2>
<p>Even with the BinaryReader/Writer being the clear winner for storing or transmitting data, I still see uses for going with the [Serialization] attribute method. Losing type information is a big deal in situations where you may not know how the object was originally stored. It&#8217;s also ridiculously simple to add support to a project. I am a big fan of the fire-and-forget methodology, and so I will be revisiting using [Serialization] in the future.</p>
<p>Using XML to store data <em>that doesn&#8217;t need to be edited by a human with a text-editor</em> is a bad idea. There&#8217;s very little benefit, and if you&#8217;re going to go that route you might as well use something like JSON, provided you don&#8217;t need to store dictionaries that aren&#8217;t &lt;string,object&gt;. (There may be a fix for that, I&#8217;m still looking and will report back when I know with any certainty).</p>
<p>Overall, the most surprising thing was that using the ISerializable Interface turned out to be slower than the built-in method. I would have figured it to be faster since you control exactly how the object gets serialized. In a future post I&#8217;ll track down exactly why this is the case.</p>
<p><span style="font-size: 20px;font-weight: bold">[References]</span></p>
<p><a title="Everything you could possibly need to know about XML Serialization" href="http://www.diranieh.com/NETSerialization/XMLSerialization.htm" target="_blank">http://www.diranieh.com/NETSerialization/XMLSerialization.htm</a></p>
<p><a title="Paul Welter's XML Serializable Generic Dictionary" href="http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx" target="_blank">http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx</a></p>
<p><a title="Pros and cons of serialization techniques" href="http://www.dotneat.net/2009/03/22/NETSerializationUsingBinaryFormaterSoapFormatterAndXmlSerializer.aspx" target="_blank">http://www.dotneat.net/2009/03/22/NETSerializationUsingBinaryFormaterSoapFormatterAndXmlSerializer.aspx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.monstersoft.com/wp/?feed=rss2&#038;p=353</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Not] Recommended For You #3</title>
		<link>http://www.monstersoft.com/wp/?p=247</link>
		<comments>http://www.monstersoft.com/wp/?p=247#comments</comments>
		<pubDate>Tue, 31 May 2011 00:26:37 +0000</pubDate>
		<dc:creator>flameshadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.monstersoft.com/wp/?p=247</guid>
		<description><![CDATA[Last time we had shopping in St. Martin. This time we have a twofer: a woman from Australia and touching nubby bits. (Those are in separate videos). Recommended For You: Kinessiology for Kids workshop from Touch for Health Recommended For You: S &#8230;<p class="read-more"><a href="http://www.monstersoft.com/wp/?p=247">Continue reading</a></p>]]></description>
			<content:encoded><![CDATA[<p>Last time we had shopping in St. Martin. This time we have a twofer: a woman from Australia and touching nubby bits.</p>
<p><span id="more-247"></span></p>
<p>(Those are in separate videos).</p>
<p>Recommended For You: <a title="Kinessiology for Kids workshop from Touch for Health" href="http://www.youtube.com/watch?v=xrDnBYir2Hk" target="_blank">Kinessiology for Kids workshop from Touch for Health</a></p>
<p>Recommended For You: <a title="S 036 Tastsinn / sensory cells in skin for touch" href="http://www.youtube.com/watch?v=sHf1fm0fgRg" target="_blank">S 036 Tastsinn / sensory cells in skin for touch</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.monstersoft.com/wp/?feed=rss2&#038;p=247</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Not] Recommended For You #2</title>
		<link>http://www.monstersoft.com/wp/?p=74</link>
		<comments>http://www.monstersoft.com/wp/?p=74#comments</comments>
		<pubDate>Tue, 24 May 2011 13:02:38 +0000</pubDate>
		<dc:creator>flameshadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Recommended For You]]></category>
		<category><![CDATA[Youtube]]></category>

		<guid isPermaLink="false">http://www.monstersoft.com/wp/?p=74</guid>
		<description><![CDATA[The last stop on this trip down the rabbit hole was a short video of a cityscape with what looked to be a fake balloon. This time we have large children trying to exercise, people being massaged, beer and coffee, &#8230;<p class="read-more"><a href="http://www.monstersoft.com/wp/?p=74">Continue reading</a></p>]]></description>
			<content:encoded><![CDATA[<p>The last stop on this trip down the rabbit hole was a short video of a cityscape with what looked to be a fake balloon. This time we have large children trying to exercise, people being massaged, beer and coffee, solar panels and hair products, all in one video!</p>
<p><span id="more-74"></span>Today we get:</p>
<p>Recommended for you: <a title="Einkaufen in St. Martin" href="http://www.youtube.com/watch?v=eKxOb_dLzLc" target="_blank">&#8220;Einkaufen in St. Martin&#8221;</a> because you watched <a title="Martin Ebner - NULLPANORAMA" href="http://www.youtube.com/watch?v=P21Dz8NYuDI&amp;feature=grec_index" target="_blank">“Martin Ebner – NULLPANORAMA”</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.monstersoft.com/wp/?feed=rss2&#038;p=74</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hexagonal Mapping (Part One): Concepts</title>
		<link>http://www.monstersoft.com/wp/?p=83</link>
		<comments>http://www.monstersoft.com/wp/?p=83#comments</comments>
		<pubDate>Thu, 19 May 2011 01:28:15 +0000</pubDate>
		<dc:creator>flameshadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.monstersoft.com/wp/?p=83</guid>
		<description><![CDATA[I&#8217;ve been wanting to do a game with a hexagonal based map for a while now. Something where the world is persistent and changes in that world are meaningful. I mentioned this to a friend and pointed to a game &#8230;<p class="read-more"><a href="http://www.monstersoft.com/wp/?p=83">Continue reading</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been wanting to do a game with a hexagonal based map for a while now. Something where the world is persistent and changes in that world are meaningful. I mentioned this to a friend and pointed to a game called CyberStorm that had similar map mechanics. It&#8217;s a BattleTech clone written by Sierra back in the 90&#8242;s, which we both thoroughly enjoyed playing as a pencil &amp; paper game. After some discussion we agreed to a collaboration. I&#8217;m not an expert and I&#8217;ve never looked into how to do hexagonal maps or what&#8217;s involved, so this will be a record of my journey into the unknown world of hexagonal mapping.</p>
<p><span id="more-83"></span></p>
<h2>[Shiny Things]</h2>
<p>As geeky as this is to admit, I really like the symmetry of hexagonal shapes. I do chainmaille as a hobby and several of my favourite weaves are 6-in-1 European and 12-in-2 Japanese.</p>
<div class="wp-caption alignright" style="width: 210px"><a href="http://www.jewelrymakingdaily.com/blogs/daily/archive/2011/01/17/learn-japanese-12-in-2-chain-maille-weave-in-6-steps.aspx" target="_blank"><img class=" " src="http://www.monstersoft.com/images/4380.Japanese6_2D00_12in2chainmaille.jpg" alt="12-in-2 Hexagonal Weave" width="200" height="188" /></a><p class="wp-caption-text">12-in-2 Hexagonal Weave by Sara Richardson</p></div>
<p>(I&#8217;m also a big fan of Fieldstone, which are 3 parallel rings interlocked with a second set of 3 parallel rings with a dihedral angle of 90°).</p>
<p>Interestingly, the image demonstrates the relationship between hexagonal shapes and circles, and is called <a title="Circle packing (wikipedia)" href="http://en.wikipedia.org/wiki/Circle_packing" target="_blank">circle packing.</a> A hexagon is the densest arrangement of equal sized circles on a 2-dimensional plane. Each cell is connected to other cells by links in increments of 60°. The above picture also foreshadows some additional features our hexagonal map will require, as represented by the purple rings. More on that in a moment.</p>
<h2>[Hextille. Rhymes with style or steel?]</h2>
<p>The first thing to define is what a grid is. In the context of a game, a grid generally represents a logical arrangement and subdivision of a playing field, and each individual location on a grid is known as a tile. Take, for example, a chessboard. The board itself is broken up into an 8&#215;8 grid of individual tiles.</p>
<div class="wp-caption alignleft" style="width: 452px"><img src="http://www.monstersoft.com/images/Chessboard.png" alt="Chessboards" width="442" height="200" /><p class="wp-caption-text">2D Chessboard (left); 3D Chessboard by Ji Lee (right)</p></div>
<p>A group of tiles is called a grid and a group of hexagonal tiles is called a hextille. I&#8217;m still unsure if it rhymes with &#8220;style&#8221; or &#8220;steel&#8221;, and it&#8217;s printed as both &#8220;hextille&#8221; and &#8220;hextile&#8221; on Wikipedia.</p>
<p>Even though they look different, the board on the left and the board on the right can be represented by the same data structure. Only the visualization of the data would need the additional information of height, which can be stored separately. From a programming perspective, this sort of grid can be easily represented by a 1- or 2-dimensional array, with the latter being more common.</p>
<p>Ok, so you could use an array to represent the grid. But, an array of <em>what?</em> For a grid as basic as chess or checkers, you might store what piece is present as an integer. That information is contained to a single tile, and it would be the equivalent of the larger chrome coloured rings above.</p>
<p>But what if you need to store more information? E.g., a maze where moving into some adjacent squares isn&#8217;t allowed, or there is some sort of cost associated with moving onto another tile. This sort of information would be akin to the purple rings in the chainmaille example above. The information is only relevant if there is an adjacent tile. We&#8217;ll need some sort of record that holds all the relevant information. In graph theory, that sort of record is called a node. Since we&#8217;re working with hexagonal shapes, naming it HexNode seems apt.</p>
<h2>[Pointy Side Up]</h2>
<p>If you are looking from above on a normal rectangular grid then each tile will have 4 adjacent neighbors (one every 90°) in the directions of left, right, down, and up. When dealing with a hextille, you end up being able to move in 6 directions (every 60°): upper-left, upper-right, lower-left, lower-right, and&#8230; well, now you have two options. You can either orient the map so you get up/down, or left/right (henceforth known as &#8220;pointy side up&#8221;). The orientation may not make much difference to an observer of the grid, as they are simply the same thing rotated 90°. However, it somewhat does matter internally because it may affect things like naming and the coordinate system.</p>
<div class="wp-caption alignright" style="width: 410px"><img src="http://www.monstersoft.com/images/HexMapOrientation.png" alt="Hex Map Orientation" width="400" height="200" /><p class="wp-caption-text">Hextille with Left/Right (left); Hextille with Up/Down (right)</p></div>
<p>It may also matter depending on how you store each node. If you were using an array, the map with the pointy side up would make more logical sense, since it&#8217;s almost the equivalent of a rectangular array with every other row shifted by 1/2 of a unit. I&#8217;ve opted for the pointy side up version for a couple of reasons. One is because it reminds me of <a title="Q*bert" href="http://www.atariage.com/development_page.html?InDevelopmentID=89" target="_blank">Q*Bert</a>. The other is because of where (0,0) is.</p>
<h2>[Where Am I?]</h2>
<p>So far we know that hexagons have a close relationship to circles. So, if you needed to decide where the origin of a circle would be, what would be the logical choice? The center.</p>
<div class="wp-caption alignleft" style="width: 336px"><img src="http://www.monstersoft.com/images/HexCoordsAndAxis2.png" alt="Hexagonal Coordinates" width="326" height="150" /><p class="wp-caption-text">Hexagonal Coordinates from Overhead (left); Right-handed Cartesian Coordinate System (right)</p></div>
<p>The image on the left (original concept was from <a title="Juha-Mikko's Blog" href="http://jmz.iki.fi/" target="_blank">Juha-Mikko&#8217;s blog</a>) places the origin in the center and shows the X- and Y-axis. Placing the origin in the center does several things to the implementation of the maps. The first is to make the maps definable by a radius. The second is the need to use an implementation that doesn&#8217;t mind negative coordinates. If you were using an array (or, specifically a jagged array), you would need to do some sort of translation from hextille coordinates to array coordinates. There&#8217;s actually an elegant solution for the negative array coordinates problem that <a title="Using Non-Zero Based Arrays" href="http://www.dev102.com/2008/11/10/10-ways-to-shoot-yourself-in-the-foot-part-a/" target="_blank">doesn&#8217;t involve shooting yourself in the foot</a>. Obviously using pascal (with its definable array subscript ranges) would be <em>a</em> solution, but I&#8217;m going to be writing this in C#. I&#8217;ll get to the actual implementation in the next post.</p>
<p>As for the axes, we&#8217;re using a right-handed coordinate system. The X value increases as you travel down and left. The Y value increases as you travel down and right. If we&#8217;re working with 3d points, the Z value would increase as you come towards the viewer. This is somewhat arbitrary and left up to personal preference.</p>
<h2>[Plan For Today, Prepare For Tomorrow]</h2>
<p>It is common knowledge that one should start small and work up. Well-designed software rarely congeals into existence after an evening of hacking it together. At this point I have a rough starting point with which to put something together and experiment with it. While hindsight is 20/20, I&#8217;m writing this without that luxury. So, I need to think ahead.</p>
<p>Here&#8217;s a list of items that I think I&#8217;ll need at some point in the future:</p>
<ul>
<li>Saving to disk (serialization)</li>
<li>Flexible data nodes for future projects</li>
<li>Path traversal including movement costs</li>
<li>Gluing hextilles together</li>
<li>Stacking hextilles on top of each other (layers)</li>
<li>Higher resolution coordinates for movement within an individual cell</li>
<li>The ability to iterate over each node</li>
</ul>
<p>Of all those, only the last two are tricky. With all this in mind, I&#8217;ll cover implementation as I go along starting in the next post.</p>
<h2>[Summary]</h2>
<p>Chainmaille is shiny. Hexagons are a dense packing of circles. Rectangular packing of tiles is called a grid. Hexagonal packing of tiles is called a hextille. Only store needed info. Pointy side is up. Origin is in the middle. No need to use arrays. Think ahead.</p>
<h2>[References]</h2>
<p><a title="12-in-2 Japanese chainmaille by Sara Richardson" href="http://www.jewelrymakingdaily.com/blogs/daily/archive/2011/01/17/learn-japanese-12-in-2-chain-maille-weave-in-6-steps.aspx" target="_blank">http://www.jewelrymakingdaily.com/blogs/daily/archive/2011/01/17/learn-japanese-12-in-2-chain-maille-weave-in-6-steps.aspx</a></p>
<p><a title="Circle Packing (Wikipedia)" href="http://en.wikipedia.org/wiki/Circle_packing" target="_blank">http://en.wikipedia.org/wiki/Circle_packing</a></p>
<p><a title="3D Chessboard by Ji Lee" href="http://pleaseenjoy.com/project.php?cat=1&amp;subcat=&amp;pid=16" target="_blank">http://pleaseenjoy.com/project.php?cat=1&amp;subcat=&amp;pid=16</a></p>
<p><a title="Hexagonal Tiling (Wikipedia)" href="http://en.wikipedia.org/wiki/Hexagonal_tiling" target="_blank">http://en.wikipedia.org/wiki/Hexagonal_tiling</a></p>
<p><a title="Mathematical Algorithms with Hextilles" href="http://www-cs-students.stanford.edu/~amitp/Articles/HexLOS.html" target="_blank">http://www-cs-students.stanford.edu/~amitp/Articles/HexLOS.html</a></p>
<p><a title="Hexagonal Maps (Dead link at the time of this writing)" href="http://web.archive.org/web/20090228074918/http://jmz.iki.fi/blog/programming/hexagonal_maps" target="_blank">http://jmz.iki.fi/blog/programming/hexagonal_maps</a> (Dead link at the time of this writing)</p>
<p><a title="Using Non-Zero Based Arrays" href="http://www.dev102.com/2008/11/10/10-ways-to-shoot-yourself-in-the-foot-part-a/" target="_blank">http://www.dev102.com/2008/11/10/10-ways-to-shoot-yourself-in-the-foot-part-a/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.monstersoft.com/wp/?feed=rss2&#038;p=83</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Not] Recommended For You #1</title>
		<link>http://www.monstersoft.com/wp/?p=7</link>
		<comments>http://www.monstersoft.com/wp/?p=7#comments</comments>
		<pubDate>Sun, 15 May 2011 08:24:17 +0000</pubDate>
		<dc:creator>flameshadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Recommended For You]]></category>
		<category><![CDATA[Youtube]]></category>

		<guid isPermaLink="false">http://www.monstersoft.com/wp/?p=7</guid>
		<description><![CDATA[Youtube has a feature called &#8220;Recommended For You&#8221;. It&#8217;s the most mind-bending bizarrely chosen list of randomness you&#8217;ve ever heard of. The first time I noticed this was when I watched a Blender 2.5 Tutorial For Beginners. What &#8212; in &#8230;<p class="read-more"><a href="http://www.monstersoft.com/wp/?p=7">Continue reading</a></p>]]></description>
			<content:encoded><![CDATA[<p>Youtube has a feature called &#8220;Recommended For You&#8221;. It&#8217;s the most mind-bending bizarrely chosen list of randomness you&#8217;ve ever heard of.</p>
<p>The first time I noticed this was when I watched a Blender 2.5 Tutorial For Beginners. What &#8212; in its infinitely confusing wisdom &#8212; did it recommend for me based on that video?</p>
<p><span id="more-7"></span></p>
<p>It recommended &#8220;Minecraft Lets Play Special&#8221;. Alright, I guess that&#8217;s not entirely unreasonable. I&#8217;ve watched a <a title="X's Minecraft Let's Play" href="http://www.youtube.com/user/davidr64yt#p/c/0/4bh4EexJO4I" target="_blank">Minecraft Let&#8217;s Play</a> in the past. Perhaps it was just a fluke.</p>
<p>A few days later a discussion arose in the ##XNA channel on FreeNode about an alien abduction game. I eventually stumbled across a video on youtube. The next day it happened again.</p>
<p>Recommended for You: <a title="Twitter und Kompetenzentwicklung" href="http://www.youtube.com/watch?v=pBvmMfs6fME&amp;feature=grec_index" target="_blank">&#8220;Twitter und Kompetenzentwicklung&#8221;</a> because you watched &#8220;Cows vs Aliens&#8221;.</p>
<p>What?</p>
<p>And then again a few days later:</p>
<p>Recommended for You: <a title="Martin Ebner - NULLPANORAMA" href="http://www.youtube.com/watch?v=P21Dz8NYuDI&amp;feature=grec_index" target="_blank">&#8220;Martin Ebner &#8211; NULLPANORAMA&#8221;</a> because you watched &#8220;Twitter und Kompetenzentwicklung&#8221;.</p>
<p>What? What?</p>
<p>I&#8217;m going to follow this to see just how deep the rabbit hole goes.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.monstersoft.com/wp/?feed=rss2&#038;p=7</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nuclear Insanity 2011</title>
		<link>http://www.monstersoft.com/wp/?p=12</link>
		<comments>http://www.monstersoft.com/wp/?p=12#comments</comments>
		<pubDate>Sat, 14 May 2011 08:36:56 +0000</pubDate>
		<dc:creator>flameshadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Nuclear Insanity]]></category>
		<category><![CDATA[Tetris]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://www.monstersoft.com/wp/?p=12</guid>
		<description><![CDATA[Many moons ago a small team of highly motivated and extremely talented people got together to make a game: a tetris clone based on another tetris clone called Atomic Tetris by Jared Tarbell. Initially we had named ours Nuclear Tetris &#8230;<p class="read-more"><a href="http://www.monstersoft.com/wp/?p=12">Continue reading</a></p>]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignleft" style="width: 330px"><img src="http://www.monstersoft.com/games/NuclearInsanity/NuclearInsanityTitle.png" alt="Nuclear Insanity Title Screen" width="320" height="193" /><p class="wp-caption-text">Nuclear Insanity</p></div>
<p>Many moons ago a small team of highly motivated and extremely talented people got together to make a game: a tetris clone based on another tetris clone called Atomic Tetris by Jared Tarbell. Initially we had named ours Nuclear Tetris and then to Nuclear Insanity (for trademark reasons). The program was a 16-bit real mode application written in a mix of assembler and pascal. It was filled with many unknown bugs, nightmarish and completely unmaintainable code, all of which relied heavily on a global variable named &#8220;q&#8221;.</p>
<p>Fast forward to the beginning of 2011 when I decided to learn XNA and C#. I figured the best way to do so would be to port something familiar, and seeing as how Nuclear Insanity no longer ran on modern hardware, it was the ideal choice.</p>
<p><span id="more-12"></span></p>
<p>There were a few technical challenges in porting a 20 year old game. I somewhat regret not keeping an active journal of the effort, as it surely would have helped others. It&#8217;s one reason I&#8217;ve started this blog.</p>
<h2>[Then]</h2>
<p>Nuclear Insanity was originally worked on by 8-10 people under the banner of Ashgon Inc. circa 1992 and was later published in April of 1993. A majority of the game code was written by me. The graphics were done by several people, most notably Ken Nichols and Payton Whitaker.</p>
<div class="wp-caption aligncenter" style="width: 330px"><img src="http://www.monstersoft.com/games/nuclear/nuke5.gif" alt="Annihilation Mode" width="320" height="200" /><p class="wp-caption-text">The Original Nuclear Insanity</p></div>
<p style="text-align: center">&nbsp;</p>
<h2>[Slightly After Then]</h2>
<p>After the commercial release of Nuclear Insanity, Justin Harker went back into the code and added proper music support. By this time we had formed the New Order Demo Group and re-released under that moniker. There were some minor modifications to the graphics and a few bugs were fixed.</p>
<h2>[Slightly Before Now]</h2>
<p>The Nuclear Insanity Project (henceforth known as NI) began in mid-January of 2011. The first priority was tracking down all the assets for the game, which included the source code, music, graphics, file formats, and tools. None of the original programs used in the making of the game still worked. Because we wrote the custom tools to make the graphics &#8212; including DannyPaint with its own clever RLE compression scheme called MOOISHI! &#8212; I had to write a <a title="Content Pipeline assemblies  " href="http://blogs.msdn.com/b/shawnhar/archive/2008/11/24/content-pipeline-assemblies.aspx" target="_blank">custom content processor</a> to <a title="&quot;For some crazy reason I'm using Deluxe Paint on the Amiga to draw my textures, so I want to be able to import them from Amiga .lbm files.&quot;" href="http://blogs.msdn.com/b/shawnhar/archive/2006/12/07/what-to-extend-in-the-content-pipeline.aspx" target="_blank">decompress the .msh files</a>.</p>
<p>My intent was to make the modern NI port fairly faithful to the original game. Most of the graphics made it back in, even some that primarily went unused. I was quite torn on whether or not to use Joel&#8217;s first graphics set, as he put a lot of effort into them. In the end I decided it better to have a near-identical clone than try to fit the older work in. However, what he did was truly a work of art considering the tools available at the time and they are worthy of inclusion here:</p>
<div class="wp-caption aligncenter" style="width: 650px"><img class=" " src="http://www.monstersoft.com/games/NuclearInsanity/NukeTetTitle.png" alt="NukeTet Title" width="640" height="200" /><p class="wp-caption-text">Akira Inspired NukeTet Title</p></div>
<div class="wp-caption aligncenter" style="width: 650px"><img class="  " src="http://www.monstersoft.com/games/NuclearInsanity/NukeTetSetup.png" alt="Title and Setup Screen" width="640" height="200" /><p class="wp-caption-text">Nuclear Tetris Title and Setup Screen</p></div>
<p>Keep in mind that neither DannyPaint nor the icon editor (MyIcon IV) had mouse support. Save for a few rendered items and procedurally generated graphics, the bitmap graphics drawn for the blocks, fonts, and the screens were all done by hand. Pixel by painstaking pixel with the occasional flood-fill, all in 256 colours.</p>
<p>At some point in the future I may go into more details about some design decisions made in porting the code. The only major change I made was the option screen. The original was a nightmare and since some of the original limitations were no longer present (e.g. being able to use any key on the keyboard) I had to redesign it.</p>
<div class="wp-caption aligncenter" style="width: 650px"><img class=" " src="http://www.monstersoft.com/games/NuclearInsanity/OptionScreens.png" alt="Original and New Option Screens" width="640" height="200" /><p class="wp-caption-text">Original Option Screen (Left) and New Option Screen (Right)</p></div>
<p>Some of the module system will be reused in upcoming projects, so I will go over those in more detail as they come up.</p>
<h2>[Now]</h2>
<p>So, that brings us to where the game is at today. It took almost exactly 2 months from start to finish, with an additional month dragging my heels on moving from <a title="Isolated Storage (MSDN)" href="http://msdn.microsoft.com/en-us/library/3ak841sy(v=vs.80).aspx" target="_blank">IsolatedStorage</a> to using <a title="What is Storage? (MSDN)" href="http://msdn.microsoft.com/en-us/library/bb200105.aspx" target="_blank">StorageDevice</a>. I&#8217;ve decided to release the code into the Public Domain, so that others may learn and use what we&#8217;ve done. You can <a title="Nuclear Insanity Source (47168095 bytes)" href="http://www.monstersoft.com/games/NuclearInsanity/NuclearInsanitySource.zip">download the Nuclear Insanity C#/XNA source </a>or<a title="Nuclear Insanity (35041891 bytes)" href="http://www.monstersoft.com/games/NuclearInsanity/NuclearInsanity.zip"> </a>just the <a title="Nuclear Insanity (35041891 bytes)" href="http://www.monstersoft.com/games/NuclearInsanity/NuclearInsanity.zip">Nuclear Insanity binaries</a>.</p>
<div class="wp-caption aligncenter" style="width: 650px"><img src="http://www.monstersoft.com/games/NuclearInsanity/NuclearInsanityOneTwoPlayer.png" alt="One and Two Player Screens" width="640" height="200" /><p class="wp-caption-text">One Player Mode (Left) and Two Player Mode (Right)</p></div>
<h2>[Epilogue: Wisdom +1]</h2>
<p>What have I learned from NI? Beyond the mostly pleasant experience of using C#/XNA, I found that the game itself is nothing special. It&#8217;s a highly polished copy of another game, which in-and-of itself is a copy of the original Tetris (doesn&#8217;t everybody make a Tetris clone at some point?). The experience, however, <em>was</em> something special. What made it so were the people working on it, from the talented artists to the awesome coders and musicians. I was lucky to be around them and inspired by them. Reaching the destination of finishing a game is very rewarding, but the journey itself is far more meaningful.</p>
<h2>[Downloads]</h2>
<p><a title="Nuclear Insanity Source" href="http://www.monstersoft.com/games/NuclearInsanity/NuclearInsanitySource.zip">http://www.monstersoft.com/games/NuclearInsanity/NuclearInsanitySource.zip</a> (47168095 bytes)</p>
<p><a title="Nuclear Insanity Binaries Only" href="http://www.monstersoft.com/games/NuclearInsanity/NuclearInsanity.zip">http://www.monstersoft.com/games/NuclearInsanity/NuclearInsanity.zip</a> (35041891 bytes)</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.monstersoft.com/wp/?feed=rss2&#038;p=12</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>And, we&#8217;re back</title>
		<link>http://www.monstersoft.com/wp/?p=5</link>
		<comments>http://www.monstersoft.com/wp/?p=5#comments</comments>
		<pubDate>Sat, 14 May 2011 06:26:53 +0000</pubDate>
		<dc:creator>flameshadow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.monstersoft.com/wp/?p=5</guid>
		<description><![CDATA[After 15 years of inactivity, we decided to fire up the ol&#8217; website again. Hope it is of some use to people.]]></description>
			<content:encoded><![CDATA[<p>After 15 years of inactivity, we decided to fire up the ol&#8217; website again. Hope it is of some use to people.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.monstersoft.com/wp/?feed=rss2&#038;p=5</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
