<?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>GoGo-Robot &#187; Developer Blog</title>
	<atom:link href="http://www.gogo-robot.com/categories/devblog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gogo-robot.com</link>
	<description>Independent Games Developer</description>
	<lastBuildDate>Fri, 27 Jan 2012 11:18:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Memory Management &#8211; Part 1</title>
		<link>http://www.gogo-robot.com/2012/01/25/memory-management-part-1/</link>
		<comments>http://www.gogo-robot.com/2012/01/25/memory-management-part-1/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 23:50:41 +0000</pubDate>
		<dc:creator>Rew</dc:creator>
				<category><![CDATA[Developer Blog]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.gogo-robot.com/?p=420</guid>
		<description><![CDATA[I was originally going to post a piece on iOS memory management, but it turned into a much larger piece on memory manangement in general. So, here&#8217;s the first part &#8211; other parts will follow later&#8230; Understanding what memory management is and why you need to do it. There are two main points that form [...]]]></description>
			<content:encoded><![CDATA[<p>I was originally going to post a piece on iOS memory management, but it turned into a much larger piece on memory manangement in general. So, here&#8217;s the first part &#8211; other parts will follow later&#8230;</p>
<p><span id="more-420"></span></p>
<h1>Understanding what memory management is and why you need to do it.</h1>
<p>There are two main points that form the basis of all of this:</p>
<ul>
<li>Every device has a limited amount of memory available, which means it can only store a limited amount of information. Imagine the memory as a pile of empty boxes, ready to be filled with stuff.</li>
<li>Every time you create an object, you are grabbing one of these empty boxes and using it to store your object in. That object will now hapilly live inside the box for the rest of its life.</li>
</ul>
<p>Note the term &#8220;<i>for the rest of its life</i>&#8221; &#8211; this is the important bit. While an object exists, it holds on to its box, so nothing else can live in it. If you want to create another object, you&#8217;ve got to grab another box from the pile for it to live in, and so on.<br /><!--more--><br />
Now, if you destroy an object, its box becomes empty again and gets thrown back onto the pile, ready to get used again.</p>
<p>OK, so now what happens if we keep creating objects, but never destroy them when we&#8217;re done using them? (Incidently, this is what is known as a <i>memory leak</i>) Well, we keep needing empty boxes to put our objects in. But remember, our device only has a limited amount of memory, so we&#8217;re going to run out eventually. And when that happens, it&#8217;s game over. A number of things can happen to your application, depending on the device and operating system, including:</p>
<ul>
<li>An exception is thrown when you try and create a new object when there&#8217;s no more space</li>
<li>The operating system can just force your application to close and grab back all of its memory without even notifying you</li>
<li>Nothing happens, but your memory allocation returns an invalid address. If you try and use this address, your application and device might just crash</li>
</ul>
<p>Obviously, we don&#8217;t want any of these to occur, so we&#8217;d better make sure we tidy up after ourselves and put the boxes back.</p>
<h1>Memory management in C</h1>
<p>Firstly, we&#8217;ll look at the basic functions for managing memory. Starting with plain C, we&#8217;ve got:</p>
<table style="border-collapse:collapse; border: 1px solid black; width: 100%;">
<tr style="border: 1px solid black; background-color: #a0a0a0;">
<td style="border: 1px solid black; padding: 0.25em;"><b>Function</b></td>
<td style="border: 1px solid black; padding: 0.25em;"><b>Description</b></td>
<td style="border: 1px solid black; padding: 0.25em;"><b>Example</b></td>
</tr>
<tr style="border: 1px solid black;">
<td style="border: 1px solid black; padding: 0.25em;"><a href="http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/">malloc</a></td>
<td style="border: 1px solid black; padding: 0.25em;">Allocates a chunk of memory from the heap*.</td>
<td style="border: 1px solid black; padding: 0.25em;"><span style="font-family:'Courier New', Monospace">char* pMyMemory = (char*)malloc(200); // Allocate a block of 200 bytes</span></td>
</tr>
<tr style="border: 1px solid black;">
<td style="border: 1px solid black; padding: 0.25em;"><a href="http://www.cplusplus.com/reference/clibrary/cstdlib/free/">free</a></td>
<td style="border: 1px solid black; padding: 0.25em;">Frees up a chunk of memory and returns it back to the heap.</td>
<td style="border: 1px solid black; padding: 0.25em;"><span style="font-family:'Courier New', Monospace">free(pMyMemory);</span></td>
</tr>
</table>
<p><i>* &#8211; The heap is our pile of boxes (i.e. all of our application&#8217;s memory)</i></p>
<p>Simple. We&#8217;ve got our function that grabs some memory, and one that puts it back. This is great for basic programs, but in larger applications, you&#8217;ll soon realise that you need to be <i>very</i> careful about what you do with that memory. Take the following:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// This function returns a copy of a C-style string</span>
<span style="color: #993333;">char</span><span style="color: #339933;">*</span> String_Copy<span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span><span style="color: #339933;">*</span> pString<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">int</span> SizeOfMemoryNeeded <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	<span style="color: #993333;">char</span><span style="color: #339933;">*</span> pMemoryToReturn <span style="color: #339933;">=</span> NULL<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Get the length of the string</span>
	SizeOfMemoryNeeded <span style="color: #339933;">=</span> strlen<span style="color: #009900;">&#40;</span>pString<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Add 1 byte on for the null terminator</span>
	<span style="color: #666666; font-style: italic;">// strlen returns the number of characters in the string,</span>
	<span style="color: #666666; font-style: italic;">// but C-style strings need a byte at the end set to 0</span>
	<span style="color: #666666; font-style: italic;">// to mark where the string stops. (This is known as being null-terminated)</span>
	SizeOfMemoryNeeded <span style="color: #339933;">+=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Allocate our memory</span>
	pMemoryToReturn <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>malloc<span style="color: #009900;">&#40;</span>SizeOfMemoryNeeded<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Copy our string</span>
	strcpy<span style="color: #009900;">&#40;</span>pMemoryToReturn<span style="color: #339933;">,</span> pString<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Return the newly allocated memory</span>
	<span style="color: #b1b100;">return</span> pMemoryToReturn<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">const</span> <span style="color: #993333;">char</span><span style="color: #339933;">*</span> pMyString <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;This is my string&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #993333;">char</span><span style="color: #339933;">*</span> pCopiedString <span style="color: #339933;">=</span> NULL<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Copy MyString</span>
	pCopiedString <span style="color: #339933;">=</span> String_Copy<span style="color: #009900;">&#40;</span>pMyString<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Now we have a pointer, pCopiedString, which</span>
	<span style="color: #666666; font-style: italic;">// points at the memory we grabbed in String_Copy.</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// ....</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// We pass our copied string into a function</span>
	SomeFunction<span style="color: #009900;">&#40;</span>pCopiedString<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// ....</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// So now we decide we're going to play nice and clean up</span>
	<span style="color: #666666; font-style: italic;">// our memory that we allocated:</span>
	free<span style="color: #009900;">&#40;</span>pCopiedString<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h1>Ownership</h1>
<p>So that&#8217;s all fine and good. We&#8217;ve played nice and put our box back on the pile when we&#8217;re done with it. Then one day, after lots of code has been added to our project, suddenly we get <b>BOOM!</b> when we try and free our memory. What gives? Well, after hours of searching, we eventually find this travesty somewhere deep in the program:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> SomeFunctionDeepInTheProgram<span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span><span style="color: #339933;">*</span> pAString<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Do some stuff</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// We don't need the string any more, so lets delete it</span>
	free<span style="color: #009900;">&#40;</span>pAString<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Gah! Whoever wrote that should be shot. It turns out that our copied string was being passed into this function, and the function was freeing up its memory ready to be used by something else.</p>
<p>The key here is <b>ownership</b>. Who&#8217;s in charge of the memory that was created in String_Copy? Who should be the one that frees it up? One good way to decide this is through the use of certain key words in our function names. We can define a simple rule that we&#8217;ll always stick to:</p>
<ul>
<li>If a function with the word Copy or Create in its name returns memory, then whoever called that function owns the memory.</li>
</ul>
<p>See how our main() function calls String_<b>Copy</b>? Under our rule, that means that the main() function is responsible for cleaning up that memory, and no one else. SomeFunctionDeepInTheProgram is being naughty, because it&#8217;s trying to free up memory that it didn&#8217;t get via a Copy or Create function. If everyone follows our simple rule, then we can avoid this situation.</p>
<p>Hopefully that gives you a bit of an introduction into why you need to really think about memory management. Next time we&#8217;ll talk about more complex memory management, garbage collectors, reference counting and automatic memory management.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gogo-robot.com/2012/01/25/memory-management-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XNA Skinned Model Animations</title>
		<link>http://www.gogo-robot.com/2011/05/30/xna-skinned-model-animations/</link>
		<comments>http://www.gogo-robot.com/2011/05/30/xna-skinned-model-animations/#comments</comments>
		<pubDate>Mon, 30 May 2011 15:36:33 +0000</pubDate>
		<dc:creator>Rew</dc:creator>
				<category><![CDATA[Developer Blog]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[skinning]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[xna]]></category>

		<guid isPermaLink="false">http://www.gogo-robot.com/?p=379</guid>
		<description><![CDATA[The Skinned Model sample from the App Hub education catalogue is great for getting animated characters into your game, but there&#8217;s a bit of a flaw with the export process. The problem is, when you export your character from 3DS Max (and possibly other modelling programs), all you get is one animation, named &#8216;Take 001&#8242;. [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://create.msdn.com/en-US/education/catalog/sample/skinned_model">Skinned Model</a> sample from the App Hub education catalogue is great for getting animated characters into your game, but there&#8217;s a bit of a flaw with the export process. The problem is, when you export your character from 3DS Max (and possibly other modelling programs), all you get is one animation, named &#8216;Take 001&#8242;. Wouldn&#8217;t it be nice if we could define different animations for different parts of the animation timeline? Well, we&#8217;re going to do just that <img src='http://www.gogo-robot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . As an added bonus, we&#8217;ll also be adding in events, so you can be notified when certain parts of your animation are hit.
<p><span id="more-379"></span></p>
<p>This tutorial is based on the Skinned Model sample, so grab it from the <a href="http://create.msdn.com/en-US/education/catalog/sample/skinned_model">App Hub</a> if you want to follow along, or skip to the end if you want the final version (which is released under the same license as the original).</p>
<p>What we&#8217;ll be doing is creating an XML file to go with our exported model, which will define our animation clips and events. The animations defined in this file will replace animations defined in the source model file. So, first thing is to define the class that will be represented by the XML file. Create a class in the SkinnedModelPipeline project named AnimationDefinition, like so:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Collections.Generic</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Text</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">Microsoft.Xna.Framework</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">Microsoft.Xna.Framework.Content</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">Microsoft.Xna.Framework.Content.Pipeline</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">Microsoft.Xna.Framework.Content.Pipeline.Serialization</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">namespace</span> SkinnedModelPipeline
<span style="color: #008000;">&#123;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// A class for storing our animation definitions</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> AnimationDefinition
    <span style="color: #008000;">&#123;</span>
        <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// The original clip name that was exported by the modelling package</span>
        <span style="color: #008080; font-style: italic;">/// Usually this will be Take 001</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> OriginalClipName
        <span style="color: #008000;">&#123;</span>
            get<span style="color: #008000;">;</span>
            set<span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// The number of frames in the original animation</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> OriginalFrameCount
        <span style="color: #008000;">&#123;</span>
            get<span style="color: #008000;">;</span>
            set<span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// A class for storing information about individual clips that we want to create</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> ClipPart
        <span style="color: #008000;">&#123;</span>
            <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
            <span style="color: #008080; font-style: italic;">/// The name we have given the clip</span>
            <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
            <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> ClipName
            <span style="color: #008000;">&#123;</span>
                get<span style="color: #008000;">;</span>
                set<span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
            <span style="color: #008080; font-style: italic;">/// The starting frame of the clip</span>
            <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
            <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> StartFrame
            <span style="color: #008000;">&#123;</span>
                get<span style="color: #008000;">;</span>
                set<span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
            <span style="color: #008080; font-style: italic;">/// The ending frame of the clip</span>
            <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
            <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> EndFrame
            <span style="color: #008000;">&#123;</span>
                get<span style="color: #008000;">;</span>
                set<span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
            <span style="color: #008080; font-style: italic;">/// A class for defining events in an animation</span>
            <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
            <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> <span style="color: #0600FF; font-weight: bold;">Event</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
                <span style="color: #008080; font-style: italic;">/// The name of the event</span>
                <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
                <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Name
                <span style="color: #008000;">&#123;</span>
                    get<span style="color: #008000;">;</span>
                    set<span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
&nbsp;
                <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
                <span style="color: #008080; font-style: italic;">/// The frame that the event fires on</span>
                <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
                <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> Keyframe
                <span style="color: #008000;">&#123;</span>
                    get<span style="color: #008000;">;</span>
                    set<span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
            <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
            <span style="color: #008080; font-style: italic;">/// Our list of events in this animation clip</span>
            <span style="color: #008080; font-style: italic;">/// Animation clips do not require events, so this is marked as optional</span>
            <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
            <span style="color: #008000;">&#91;</span>Microsoft<span style="color: #008000;">.</span><span style="color: #0000FF;">Xna</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Framework</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Content</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ContentSerializer</span><span style="color: #008000;">&#40;</span>Optional <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#93;</span>
            <span style="color: #0600FF; font-weight: bold;">public</span> List<span style="color: #008000;">&lt;</span><span style="color: #0600FF; font-weight: bold;">Event</span><span style="color: #008000;">&gt;</span> Events
            <span style="color: #008000;">&#123;</span>
                get<span style="color: #008000;">;</span>
                set<span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// The list of clip parts that we are breaking the original clip into</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> List<span style="color: #008000;">&lt;</span>ClipPart<span style="color: #008000;">&gt;</span> ClipParts
        <span style="color: #008000;">&#123;</span>
            get<span style="color: #008000;">;</span>
            set<span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

</p>
<p>Next, we&#8217;ll need to modify the runtime project to add information about our events to the animations. Create a class in the SkinnedModelWindows project named AnimationEvent, with this in it:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080;">#region Using Statements</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Collections.Generic</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Linq</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Text</span><span style="color: #008000;">;</span>
<span style="color: #008080;">#endregion</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">namespace</span> SkinnedModel
<span style="color: #008000;">&#123;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Information about an event in our animation</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> AnimationEvent
    <span style="color: #008000;">&#123;</span>
        <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// The name of the event</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">String</span> EventName
        <span style="color: #008000;">&#123;</span>
            get<span style="color: #008000;">;</span>
            set<span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// The time of the event</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> TimeSpan EventTime
        <span style="color: #008000;">&#123;</span>
            get<span style="color: #008000;">;</span>
            set<span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

</p>
<p>Now, we need to add our events store to the animation clip, as well as the clip name. So open up AnimationClip.cs, and add this to the end of the class:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">	<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// Callback events for the animation clips</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">&#91;</span>ContentSerializer<span style="color: #008000;">&#93;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> List<span style="color: #008000;">&lt;</span>AnimationEvent<span style="color: #008000;">&gt;</span> Events <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #0600FF; font-weight: bold;">private</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
&nbsp;
	<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// The name of the clip</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">&#91;</span>ContentSerializer<span style="color: #008000;">&#93;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Name <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #0600FF; font-weight: bold;">private</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span></pre></div></div>

</p>
<p>We also need to modify the constructor so that we can pass in the list of animation events when we create the clip. Our new constructor looks like this:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">	<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// Constructs a new animation clip object.</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> AnimationClip<span style="color: #008000;">&#40;</span>TimeSpan duration, List<span style="color: #008000;">&lt;</span>Keyframe<span style="color: #008000;">&gt;</span> keyframes, List<span style="color: #008000;">&lt;</span>AnimationEvent<span style="color: #008000;">&gt;</span> events, <span style="color: #6666cc; font-weight: bold;">string</span> name<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            Duration <span style="color: #008000;">=</span> duration<span style="color: #008000;">;</span>
            Keyframes <span style="color: #008000;">=</span> keyframes<span style="color: #008000;">;</span>
            Events <span style="color: #008000;">=</span> events<span style="color: #008000;">;</span>
            Name <span style="color: #008000;">=</span> name<span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span></pre></div></div>

</p>
<p>Almost there. We need to modify the SkinnedModelProcessor class so that it reads in our XML files describing our animations and stores them in the model file that it generates, replacing the original animation (the Take 001). So, in SkinnedModelProcessor.cs, in the ProcessAnimations function, we need to first check if an animation definition file exists that we will use to override the ones in the model. By having this check, it means that we don&#8217;t need to create an animation definition for every skinned model, just the ones that we want custom animations on. You&#8217;ll also need to modify the ProcessAnimations function to take two extra parameters, which are the ContentProcessorContext and ContentIdentity. We use these to get information about the current file we are processing, so we can look for an animation definition with the same name. The below code is the updated ProcessAnimations function:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">        <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// Converts an intermediate format content pipeline AnimationContentDictionary</span>
        <span style="color: #008080; font-style: italic;">/// object to our runtime AnimationClip format.</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">static</span> Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, AnimationClip<span style="color: #008000;">&gt;</span> ProcessAnimations<span style="color: #008000;">&#40;</span>
            AnimationContentDictionary animations, IList<span style="color: #008000;">&lt;</span>BoneContent<span style="color: #008000;">&gt;</span> bones,
            ContentProcessorContext context, ContentIdentity sourceIdentity<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #008080; font-style: italic;">// Build up a table mapping bone names to indices.</span>
            Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, <span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&gt;</span> boneMap <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, <span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> i <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> bones<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #6666cc; font-weight: bold;">string</span> boneName <span style="color: #008000;">=</span> bones<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span><span style="color: #008000;">;</span>
&nbsp;
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">!</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IsNullOrEmpty</span><span style="color: #008000;">&#40;</span>boneName<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
                    boneMap<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>boneName, i<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// Convert each animation in turn.</span>
            Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, AnimationClip<span style="color: #008000;">&gt;</span> animationClips<span style="color: #008000;">;</span>
            animationClips <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, AnimationClip<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// We process the original animation first, so we can use their keyframes</span>
            <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>KeyValuePair<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, AnimationContent<span style="color: #008000;">&gt;</span> animation <span style="color: #0600FF; font-weight: bold;">in</span> animations<span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                AnimationClip processed <span style="color: #008000;">=</span> ProcessAnimation<span style="color: #008000;">&#40;</span>animation<span style="color: #008000;">.</span><span style="color: #0000FF;">Value</span>, boneMap, animation<span style="color: #008000;">.</span><span style="color: #0000FF;">Key</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                animationClips<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>animation<span style="color: #008000;">.</span><span style="color: #0000FF;">Key</span>, processed<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// Check to see if there's an animation clip definition</span>
            <span style="color: #008080; font-style: italic;">// Here, we're checking for a file with the _Anims suffix.</span>
            <span style="color: #008080; font-style: italic;">// So, if your model is named dude.fbx, we'd add dude_Anims.xml in the same folder</span>
            <span style="color: #008080; font-style: italic;">// and the pipeline will see the file and use it to override the animations in the</span>
            <span style="color: #008080; font-style: italic;">// original model file.</span>
            <span style="color: #6666cc; font-weight: bold;">string</span> SourceModelFile <span style="color: #008000;">=</span> sourceIdentity<span style="color: #008000;">.</span><span style="color: #0000FF;">SourceFilename</span><span style="color: #008000;">;</span>
            <span style="color: #6666cc; font-weight: bold;">string</span> SourcePath <span style="color: #008000;">=</span> Path<span style="color: #008000;">.</span><span style="color: #0000FF;">GetDirectoryName</span><span style="color: #008000;">&#40;</span>SourceModelFile<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #6666cc; font-weight: bold;">string</span> AnimFilename <span style="color: #008000;">=</span> Path<span style="color: #008000;">.</span><span style="color: #0000FF;">GetFileNameWithoutExtension</span><span style="color: #008000;">&#40;</span>SourceModelFile<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            AnimFilename <span style="color: #008000;">+=</span> <span style="color: #666666;">&quot;_Anims.xml&quot;</span><span style="color: #008000;">;</span>
            <span style="color: #6666cc; font-weight: bold;">string</span> AnimPath <span style="color: #008000;">=</span> Path<span style="color: #008000;">.</span><span style="color: #0000FF;">Combine</span><span style="color: #008000;">&#40;</span>SourcePath, AnimFilename<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>File<span style="color: #008000;">.</span><span style="color: #0000FF;">Exists</span><span style="color: #008000;">&#40;</span>AnimPath<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">// Add the filename as a dependency, so if it changes, the model is rebuilt</span>
                context<span style="color: #008000;">.</span><span style="color: #0000FF;">AddDependency</span><span style="color: #008000;">&#40;</span>AnimPath<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                <span style="color: #008080; font-style: italic;">// Load the animation definition from the XML file</span>
                AnimationDefinition AnimDef <span style="color: #008000;">=</span> context<span style="color: #008000;">.</span><span style="color: #0000FF;">BuildAndLoadAsset</span><span style="color: #008000;">&lt;</span>XmlImporter, AnimationDefinition<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> ExternalReference<span style="color: #008000;">&lt;</span>XmlImporter<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span>AnimPath<span style="color: #008000;">&#41;</span>, <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                <span style="color: #008080; font-style: italic;">// Break up the original animation clips into our new clips</span>
                <span style="color: #008080; font-style: italic;">// First, we check if the clips contains our clip to break up</span>
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>animationClips<span style="color: #008000;">.</span><span style="color: #0000FF;">ContainsKey</span><span style="color: #008000;">&#40;</span>AnimDef<span style="color: #008000;">.</span><span style="color: #0000FF;">OriginalClipName</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    <span style="color: #008080; font-style: italic;">// Grab the main clip that we are using</span>
                    AnimationClip MainClip <span style="color: #008000;">=</span> animationClips<span style="color: #008000;">&#91;</span>AnimDef<span style="color: #008000;">.</span><span style="color: #0000FF;">OriginalClipName</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span>
&nbsp;
                    <span style="color: #008080; font-style: italic;">// Now remove the original clip from our animations</span>
                    animationClips<span style="color: #008000;">.</span><span style="color: #0000FF;">Remove</span><span style="color: #008000;">&#40;</span>AnimDef<span style="color: #008000;">.</span><span style="color: #0000FF;">OriginalClipName</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                    <span style="color: #008080; font-style: italic;">// Process each of our new animation clip parts</span>
                    <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>AnimationDefinition<span style="color: #008000;">.</span><span style="color: #0000FF;">ClipPart</span> Part <span style="color: #0600FF; font-weight: bold;">in</span> AnimDef<span style="color: #008000;">.</span><span style="color: #0000FF;">ClipParts</span><span style="color: #008000;">&#41;</span>
                    <span style="color: #008000;">&#123;</span>
                        <span style="color: #008080; font-style: italic;">// Calculate the frame times</span>
                        TimeSpan StartTime <span style="color: #008000;">=</span> GetTimeSpanForFrame<span style="color: #008000;">&#40;</span>Part<span style="color: #008000;">.</span><span style="color: #0000FF;">StartFrame</span>, AnimDef<span style="color: #008000;">.</span><span style="color: #0000FF;">OriginalFrameCount</span>, MainClip<span style="color: #008000;">.</span><span style="color: #0000FF;">Duration</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Ticks</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                        TimeSpan EndTime <span style="color: #008000;">=</span> GetTimeSpanForFrame<span style="color: #008000;">&#40;</span>Part<span style="color: #008000;">.</span><span style="color: #0000FF;">EndFrame</span>, AnimDef<span style="color: #008000;">.</span><span style="color: #0000FF;">OriginalFrameCount</span>, MainClip<span style="color: #008000;">.</span><span style="color: #0000FF;">Duration</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Ticks</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                        <span style="color: #008080; font-style: italic;">// Get all the keyframes for the animation clip</span>
                        <span style="color: #008080; font-style: italic;">// that fall within the start and end time</span>
                        List<span style="color: #008000;">&lt;</span>Keyframe<span style="color: #008000;">&gt;</span> Keyframes <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span>Keyframe<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                        <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>Keyframe AnimFrame <span style="color: #0600FF; font-weight: bold;">in</span> MainClip<span style="color: #008000;">.</span><span style="color: #0000FF;">Keyframes</span><span style="color: #008000;">&#41;</span>
                        <span style="color: #008000;">&#123;</span>
                            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>AnimFrame<span style="color: #008000;">.</span><span style="color: #0000FF;">Time</span> <span style="color: #008000;">&gt;=</span> StartTime<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span>AnimFrame<span style="color: #008000;">.</span><span style="color: #0000FF;">Time</span> <span style="color: #008000;">&lt;=</span> EndTime<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
                            <span style="color: #008000;">&#123;</span>
                                Keyframe NewFrame <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Keyframe<span style="color: #008000;">&#40;</span>AnimFrame<span style="color: #008000;">.</span><span style="color: #0000FF;">Bone</span>, AnimFrame<span style="color: #008000;">.</span><span style="color: #0000FF;">Time</span> <span style="color: #008000;">-</span> StartTime, AnimFrame<span style="color: #008000;">.</span><span style="color: #0000FF;">Transform</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                                Keyframes<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>NewFrame<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                            <span style="color: #008000;">&#125;</span>
                        <span style="color: #008000;">&#125;</span>
&nbsp;
                        <span style="color: #008080; font-style: italic;">// Process the events</span>
                        List<span style="color: #008000;">&lt;</span>AnimationEvent<span style="color: #008000;">&gt;</span> Events <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span>AnimationEvent<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>Part<span style="color: #008000;">.</span><span style="color: #0000FF;">Events</span> <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
                        <span style="color: #008000;">&#123;</span>
                            <span style="color: #008080; font-style: italic;">// Process each event</span>
                            <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>AnimationDefinition<span style="color: #008000;">.</span><span style="color: #0000FF;">ClipPart</span><span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">Event</span> <span style="color: #0600FF; font-weight: bold;">Event</span> <span style="color: #0600FF; font-weight: bold;">in</span> Part<span style="color: #008000;">.</span><span style="color: #0000FF;">Events</span><span style="color: #008000;">&#41;</span>
                            <span style="color: #008000;">&#123;</span>
                                <span style="color: #008080; font-style: italic;">// Get the event time within the animation</span>
                                TimeSpan EventTime <span style="color: #008000;">=</span> GetTimeSpanForFrame<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">Event</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Keyframe</span>, AnimDef<span style="color: #008000;">.</span><span style="color: #0000FF;">OriginalFrameCount</span>, MainClip<span style="color: #008000;">.</span><span style="color: #0000FF;">Duration</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Ticks</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                                <span style="color: #008080; font-style: italic;">// Offset the event time so it is relative to the start of the animation</span>
                                EventTime <span style="color: #008000;">-=</span> StartTime<span style="color: #008000;">;</span>
&nbsp;
                                <span style="color: #008080; font-style: italic;">// Create the event</span>
                                AnimationEvent NewEvent <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> AnimationEvent<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                                NewEvent<span style="color: #008000;">.</span><span style="color: #0000FF;">EventTime</span> <span style="color: #008000;">=</span> EventTime<span style="color: #008000;">;</span>
                                NewEvent<span style="color: #008000;">.</span><span style="color: #0000FF;">EventName</span> <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">Event</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span><span style="color: #008000;">;</span>
                                Events<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>NewEvent<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                            <span style="color: #008000;">&#125;</span>
                        <span style="color: #008000;">&#125;</span>
&nbsp;
                        <span style="color: #008080; font-style: italic;">// Create the clip</span>
                        AnimationClip NewClip <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> AnimationClip<span style="color: #008000;">&#40;</span>EndTime <span style="color: #008000;">-</span> StartTime, Keyframes, Events, Part<span style="color: #008000;">.</span><span style="color: #0000FF;">ClipName</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                        animationClips<span style="color: #008000;">&#91;</span>Part<span style="color: #008000;">.</span><span style="color: #0000FF;">ClipName</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> NewClip<span style="color: #008000;">;</span>
                    <span style="color: #008000;">&#125;</span>
                <span style="color: #008000;">&#125;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>animationClips<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span> <span style="color: #008000;">==</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> InvalidContentException<span style="color: #008000;">&#40;</span>
                            <span style="color: #666666;">&quot;Input file does not contain any animations.&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">return</span> animationClips<span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// Gets a TimeSpan value for a frame index in an animation</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> TimeSpan GetTimeSpanForFrame<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> FrameIndex, <span style="color: #6666cc; font-weight: bold;">int</span> TotalFrameCount, <span style="color: #6666cc; font-weight: bold;">long</span> TotalTicks<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #6666cc; font-weight: bold;">float</span> MaxFrameIndex <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">float</span><span style="color: #008000;">&#41;</span>TotalFrameCount <span style="color: #008000;">-</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
            <span style="color: #6666cc; font-weight: bold;">float</span> AmountOfAnimation <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">float</span><span style="color: #008000;">&#41;</span>FrameIndex <span style="color: #008000;">/</span> MaxFrameIndex<span style="color: #008000;">;</span>
            <span style="color: #6666cc; font-weight: bold;">float</span> NumTicks <span style="color: #008000;">=</span> AmountOfAnimation <span style="color: #008000;">*</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">float</span><span style="color: #008000;">&#41;</span>TotalTicks<span style="color: #008000;">;</span>
            <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">new</span> TimeSpan<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">long</span><span style="color: #008000;">&#41;</span>NumTicks<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span></pre></div></div>

</p>
<p>What we do is process the original animations, so that all the keyframe data is there, then we check for an animation definition file and, if it exists, use it to replace the animation clips from the original model. We also need to modify ProcessAnimation to handle the new AnimationClip constructor:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">        <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// Converts an intermediate format content pipeline AnimationContent</span>
        <span style="color: #008080; font-style: italic;">/// object to our runtime AnimationClip format.</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">static</span> AnimationClip ProcessAnimation<span style="color: #008000;">&#40;</span>AnimationContent animation,
                                              Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, <span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&gt;</span> boneMap,
                                              <span style="color: #6666cc; font-weight: bold;">string</span> clipName<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            List<span style="color: #008000;">&lt;</span>Keyframe<span style="color: #008000;">&gt;</span> keyframes <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span>Keyframe<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// For each input animation channel.</span>
            <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>KeyValuePair<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, AnimationChannel<span style="color: #008000;">&gt;</span> channel <span style="color: #0600FF; font-weight: bold;">in</span>
                animation<span style="color: #008000;">.</span><span style="color: #0000FF;">Channels</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">// Look up what bone this channel is controlling.</span>
                <span style="color: #6666cc; font-weight: bold;">int</span> boneIndex<span style="color: #008000;">;</span>
&nbsp;
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">!</span>boneMap<span style="color: #008000;">.</span><span style="color: #0000FF;">TryGetValue</span><span style="color: #008000;">&#40;</span>channel<span style="color: #008000;">.</span><span style="color: #0000FF;">Key</span>, <span style="color: #0600FF; font-weight: bold;">out</span> boneIndex<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> InvalidContentException<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Format</span><span style="color: #008000;">&#40;</span>
                        <span style="color: #666666;">&quot;Found animation for bone '{0}', &quot;</span> <span style="color: #008000;">+</span>
                        <span style="color: #666666;">&quot;which is not part of the skeleton.&quot;</span>, channel<span style="color: #008000;">.</span><span style="color: #0000FF;">Key</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
&nbsp;
                <span style="color: #008080; font-style: italic;">// Convert the keyframe data.</span>
                <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>AnimationKeyframe keyframe <span style="color: #0600FF; font-weight: bold;">in</span> channel<span style="color: #008000;">.</span><span style="color: #0000FF;">Value</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    keyframes<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> Keyframe<span style="color: #008000;">&#40;</span>boneIndex, keyframe<span style="color: #008000;">.</span><span style="color: #0000FF;">Time</span>,
                                               keyframe<span style="color: #008000;">.</span><span style="color: #0000FF;">Transform</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// Sort the merged keyframes by time.</span>
            keyframes<span style="color: #008000;">.</span><span style="color: #0000FF;">Sort</span><span style="color: #008000;">&#40;</span>CompareKeyframeTimes<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>keyframes<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span> <span style="color: #008000;">==</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span>
                <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> InvalidContentException<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Animation has no keyframes.&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>animation<span style="color: #008000;">.</span><span style="color: #0000FF;">Duration</span> <span style="color: #008000;">&lt;=</span> TimeSpan<span style="color: #008000;">.</span><span style="color: #0000FF;">Zero</span><span style="color: #008000;">&#41;</span>
                <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> InvalidContentException<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Animation has a zero duration.&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">new</span> AnimationClip<span style="color: #008000;">&#40;</span>animation<span style="color: #008000;">.</span><span style="color: #0000FF;">Duration</span>, keyframes, <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span>AnimationEvent<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, clipName<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span></pre></div></div>

</p>
<p>OK, so now we can override animations in the models using our XML file. Before I show you an example file, there&#8217;s one last thing to do, which is to add in the event callback system into the runtime. So, we need to add in a place to register our event callbacks into the AnimationPlayer class. At the end of the &#8216;Fields&#8217; region, we need to add:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">	<span style="color: #008080; font-style: italic;">// The delegate template for the event callbacks</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">delegate</span> <span style="color: #6666cc; font-weight: bold;">void</span> EventCallback<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> <span style="color: #0600FF; font-weight: bold;">Event</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">// The reigstered events</span>
        Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, EventCallback<span style="color: #008000;">&gt;&gt;</span> registeredEvents <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, EventCallback<span style="color: #008000;">&gt;&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, EventCallback<span style="color: #008000;">&gt;&gt;</span> RegisteredEvents
        <span style="color: #008000;">&#123;</span>
            get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> registeredEvents<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span></pre></div></div>

</p>
<p>And initialise the registeredEvents dictionary in the constructor:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">	<span style="color: #008080; font-style: italic;">// Construct the event dictionaries for each clip</span>
        <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> clipName <span style="color: #0600FF; font-weight: bold;">in</span> skinningData<span style="color: #008000;">.</span><span style="color: #0000FF;">AnimationClips</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Keys</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            registeredEvents<span style="color: #008000;">&#91;</span>clipName<span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, EventCallback<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span></pre></div></div>

</p>
<p>Now we can add events, so the last thing to do is to add the code that calls them, then we&#8217;ll be done. In the UpdateBoneTransforms function in AnimationPlayer, we need to modify it like so:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">        <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// Helper used by the Update method to refresh the BoneTransforms data.</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> UpdateBoneTransforms<span style="color: #008000;">&#40;</span>TimeSpan time, <span style="color: #6666cc; font-weight: bold;">bool</span> relativeToCurrentTime<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>currentClipValue <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
                <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> InvalidOperationException<span style="color: #008000;">&#40;</span>
                            <span style="color: #666666;">&quot;AnimationPlayer.Update was called before StartClip&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// Store the previous time</span>
            TimeSpan lastTime <span style="color: #008000;">=</span> time<span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// Update the animation position.</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>relativeToCurrentTime<span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                lastTime <span style="color: #008000;">=</span> currentTimeValue<span style="color: #008000;">;</span>
                time <span style="color: #008000;">+=</span> currentTimeValue<span style="color: #008000;">;</span>
&nbsp;
                <span style="color: #008080; font-style: italic;">// Check for events</span>
                CheckEvents<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">ref</span> time, <span style="color: #0600FF; font-weight: bold;">ref</span> lastTime<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                <span style="color: #008080; font-style: italic;">// If we reached the end, loop back to the start.</span>
                <span style="color: #6666cc; font-weight: bold;">bool</span> hasLooped <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span>
                <span style="color: #0600FF; font-weight: bold;">while</span> <span style="color: #008000;">&#40;</span>time <span style="color: #008000;">&gt;=</span> currentClipValue<span style="color: #008000;">.</span><span style="color: #0000FF;">Duration</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    hasLooped <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">;</span>
                    time <span style="color: #008000;">-=</span> currentClipValue<span style="color: #008000;">.</span><span style="color: #0000FF;">Duration</span><span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
&nbsp;
                <span style="color: #008080; font-style: italic;">// If we've looped, reprocess the events</span>
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>hasLooped<span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    CheckEvents<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">ref</span> time, <span style="color: #0600FF; font-weight: bold;">ref</span> lastTime<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>time <span style="color: #008000;">&lt;</span> TimeSpan<span style="color: #008000;">.</span><span style="color: #0000FF;">Zero</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">||</span> <span style="color: #008000;">&#40;</span>time <span style="color: #008000;">&gt;=</span> currentClipValue<span style="color: #008000;">.</span><span style="color: #0000FF;">Duration</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
                <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> ArgumentOutOfRangeException<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;time&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// If the position moved backwards, reset the keyframe index.</span>
            <span style="color: #6666cc; font-weight: bold;">bool</span> HasResetKeyframe <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>time <span style="color: #008000;">&lt;</span> currentTimeValue<span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                HasResetKeyframe <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">;</span>
                currentKeyframe <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span>
                skinningDataValue<span style="color: #008000;">.</span><span style="color: #0000FF;">BindPose</span><span style="color: #008000;">.</span><span style="color: #0000FF;">CopyTo</span><span style="color: #008000;">&#40;</span>boneTransforms, <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            currentTimeValue <span style="color: #008000;">=</span> time<span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// Read keyframe matrices.</span>
            IList<span style="color: #008000;">&lt;</span>Keyframe<span style="color: #008000;">&gt;</span> keyframes <span style="color: #008000;">=</span> currentClipValue<span style="color: #008000;">.</span><span style="color: #0000FF;">Keyframes</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">while</span> <span style="color: #008000;">&#40;</span>currentKeyframe <span style="color: #008000;">&lt;</span> keyframes<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                Keyframe keyframe <span style="color: #008000;">=</span> keyframes<span style="color: #008000;">&#91;</span>currentKeyframe<span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span>
&nbsp;
                <span style="color: #008080; font-style: italic;">// Stop when we've read up to the current time position.</span>
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>keyframe<span style="color: #008000;">.</span><span style="color: #0000FF;">Time</span> <span style="color: #008000;">&gt;</span> currentTimeValue<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">!</span>HasResetKeyframe<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
                    <span style="color: #0600FF; font-weight: bold;">break</span><span style="color: #008000;">;</span>
&nbsp;
                <span style="color: #008080; font-style: italic;">// Use this keyframe.</span>
                boneTransforms<span style="color: #008000;">&#91;</span>keyframe<span style="color: #008000;">.</span><span style="color: #0000FF;">Bone</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> keyframe<span style="color: #008000;">.</span><span style="color: #0000FF;">Transform</span><span style="color: #008000;">;</span>
&nbsp;
                currentKeyframe<span style="color: #008000;">++;</span>
&nbsp;
                <span style="color: #0600FF; font-weight: bold;">if</span><span style="color: #008000;">&#40;</span>HasResetKeyframe<span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    currentTimeValue <span style="color: #008000;">=</span> keyframe<span style="color: #008000;">.</span><span style="color: #0000FF;">Time</span><span style="color: #008000;">;</span>
                    HasResetKeyframe <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span></pre></div></div>

</p>
<p>And add the CheckEvents function:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">        <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// Checks to see if any events have passed</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">void</span> CheckEvents<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">ref</span> TimeSpan time, <span style="color: #0600FF; font-weight: bold;">ref</span> TimeSpan lastTime<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> eventName <span style="color: #0600FF; font-weight: bold;">in</span> registeredEvents<span style="color: #008000;">&#91;</span>currentClipValue<span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Keys</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">// Find the event</span>
                <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>AnimationEvent animEvent <span style="color: #0600FF; font-weight: bold;">in</span> currentClipValue<span style="color: #008000;">.</span><span style="color: #0000FF;">Events</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>animEvent<span style="color: #008000;">.</span><span style="color: #0000FF;">EventName</span> <span style="color: #008000;">==</span> eventName<span style="color: #008000;">&#41;</span>
                    <span style="color: #008000;">&#123;</span>
                        TimeSpan eventTime <span style="color: #008000;">=</span> animEvent<span style="color: #008000;">.</span><span style="color: #0000FF;">EventTime</span><span style="color: #008000;">;</span>
                        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>lastTime <span style="color: #008000;">&lt;</span> eventTime<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span>time <span style="color: #008000;">&gt;=</span> eventTime<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
                        <span style="color: #008000;">&#123;</span>
                            <span style="color: #008080; font-style: italic;">// Call the event</span>
                            registeredEvents<span style="color: #008000;">&#91;</span>currentClipValue<span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span>eventName<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span>eventName<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                        <span style="color: #008000;">&#125;</span>
                    <span style="color: #008000;">&#125;</span>
                <span style="color: #008000;">&#125;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span></pre></div></div>

</p>
<p>So now we can define custom animations with events. Lets see it in action&#8230;</p>
<p>Add a new file to your content project, giving it the same name as the model, but with _Anims.xml. In our case, our model file is dude.fbx, so we want dude_Anims.xml. We don&#8217;t actually want the content pipeline to build this directly, so set the Build Action property to None, the Content Processor to No Processing Required, and Copy to Output Directory to Do not copy. Our XML looks like this:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;XnaContent<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Asset</span> <span style="color: #000066;">Type</span>=<span style="color: #ff0000;">&quot;SkinnedModelPipeline.AnimationDefinition&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
    <span style="color: #808080; font-style: italic;">&lt;!-- The original name of the clip we are breaking up --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;OriginalClipName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Take 001<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/OriginalClipName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #808080; font-style: italic;">&lt;!-- The total number of frames in the original clip --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;OriginalFrameCount<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>100<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/OriginalFrameCount<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #808080; font-style: italic;">&lt;!-- The new parts we want --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ClipParts<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
      <span style="color: #808080; font-style: italic;">&lt;!-- Each item is one of our new clips --&gt;</span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Item<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ClipName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Idle<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ClipName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;StartFrame<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/StartFrame<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;EndFrame<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>50<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/EndFrame<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Item<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Item<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ClipName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Fire<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ClipName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;StartFrame<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>51<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/StartFrame<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;EndFrame<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>99<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/EndFrame<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- We can register events in this clip, so we can know when certain frames are hit --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Events<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Item<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>FireFrame<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Keyframe<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>70<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Keyframe<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Item<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Events<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Item<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ClipParts<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Asset<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/XnaContent<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

</p>
<p>Now we can play our new clips like normal. We can also add callbacks for events. For example, the FireFrame event, we add like this:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">            <span style="color: #008080; font-style: italic;">// Create an animation player, and start decoding an animation clip.</span>
            animationPlayer <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> AnimationPlayer<span style="color: #008000;">&#40;</span>skinningData<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// Register an event</span>
            animationPlayer<span style="color: #008000;">.</span><span style="color: #0000FF;">RegisteredEvents</span><span style="color: #008000;">&#91;</span><span style="color: #666666;">&quot;Fire&quot;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;FireFrame&quot;</span>, <span style="color: #008000;">new</span> AnimationPlayer<span style="color: #008000;">.</span><span style="color: #0000FF;">EventCallback</span><span style="color: #008000;">&#40;</span>OnFire<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            AnimationClip clip <span style="color: #008000;">=</span> skinningData<span style="color: #008000;">.</span><span style="color: #0000FF;">AnimationClips</span><span style="color: #008000;">&#91;</span><span style="color: #666666;">&quot;Fire&quot;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span>
&nbsp;
            animationPlayer<span style="color: #008000;">.</span><span style="color: #0000FF;">StartClip</span><span style="color: #008000;">&#40;</span>clip<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

</p>
<p>And our function just looks like this:</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">        <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">void</span> OnFire<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> EventName<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #008080; font-style: italic;">// Do something here like create a bullet</span>
        <span style="color: #008000;">&#125;</span></pre></div></div>

</p>
<p>So there you have it. You can download the updated sample <a href="downloads/skinnedmodelsample/SkinningSample_4_0_WithCustomAnims.zip">here</a>. You can use the &#8217;1&#8242; and &#8217;2&#8242; keys to switch between animation clips. The second one has a callback registered to it. One thing to note is that you&#8217;ll have to make sure you do a Rebuild Solution if you&#8217;re adding an animation XML to an existing model, because the content pipeline doesn&#8217;t know that the model depends on the animation definition until after it has built it once with the animation file there. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gogo-robot.com/2011/05/30/xna-skinned-model-animations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Texture Atlas (Sprite Sheet) Generator</title>
		<link>http://www.gogo-robot.com/2010/03/20/texture-atlas-sprite-sheet-generator/</link>
		<comments>http://www.gogo-robot.com/2010/03/20/texture-atlas-sprite-sheet-generator/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 16:47:50 +0000</pubDate>
		<dc:creator>Rew</dc:creator>
				<category><![CDATA[Developer Blog]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[sprite sheet]]></category>
		<category><![CDATA[texture atlas]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[xna]]></category>

		<guid isPermaLink="false">http://www.gogo-robot.com/?p=206</guid>
		<description><![CDATA[A texture atlas, or sprite sheet, is a single image containing a number of smaller textures or sprites. This is useful as it is more efficient for the graphics card to process (it doesn&#8217;t have to keep switching textures when drawing different textures, as it can just use the single texture and sample from different [...]]]></description>
			<content:encoded><![CDATA[<p>A texture atlas, or sprite sheet, is a single image containing a number of smaller textures or sprites. This is useful as it is more efficient for the graphics card to process (it doesn&#8217;t have to keep switching textures when drawing different textures, as it can just use the single texture and sample from different parts of it). It is also faster to load into RAM, as you are only loading in one image, as opposed to several smaller ones, so the loading can be done in one stage.</p>
<p><span id="more-206"></span></p>
<p>It is useful to be able to quickly and easily generate texture atlases from a number of source sprites to speed up development. A useful tool when developing using the XNA framework is the <a href="http://creators.xna.com/en-GB/sample/spritesheet">SpriteSheet Sample</a> available on the XNA Creators Club website. One downside of this, however, is that you must still manually generate the XML file list by hand, which can be a pain if you have a lot of textures to place on the sprite sheet. Another is that it is XNA only <img src='http://www.gogo-robot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Because we also do development on the iPhone, it was useful to have a similar generator for that platform, as well as for the XNA framework, so we created a tool to easily generate the texture atlases for us. The packing code is based on the SpriteSheet Sample code, though the tool is written in plain .NET, so does not require the XNA framework to be installed (though it does require the .NET framework). The tool can produce a PNG file with the combined textures, as well as an accompanying binary file, called a TXA file, with the information on each of the packed textures. It also supports removing transparent borders from textures to produce a more compact output. It can also optionally produce a C style header with enums in, so you don&#8217;t have to look up the textures by their names.</p>
<p>The help files for the texture atlas generator tool contain information on the format of the TXA files, so you can write your own loaders if you wish.</p>
<p>As well as the PNG + TXA combination, the tool can produce an XNA XML file (and optionally a C# file with enums in) which can be imported into your Content project to build the sprite sheet during compile time. You do need to include the XNA projects in yours to access the Content Processor and runtime types. The runtime library also includes extensions to the SpriteBatch class, to make it easier to draw using the textures.</p>
<p>Finally, there is a runtime library to load the texture atlas on an iPhone. The iPhone code uses the PVRTexture class from Apple&#8217;s sample code, so you can convert the PNG to a PVR if you wish using Apple&#8217;s texturetool (though this can be problematic as the textures may &#8216;bleed&#8217; into each other). The iPhone runtime library also requires <a href="http://www.zlib.net/">zlib</a> and <a href="http://www.libpng.org/pub/png/libpng.html">libpng</a></p>
<p>Each zip contains a Readme.txt file containing license information and other tips. You&#8217;re pretty much free to do what you want with these things, use them however you see fit (commercial or non-commercial), but remember they are provided as-is, and we accept no responsibility for anything <img src='http://www.gogo-robot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  We&#8217;ve tried to tidy them up to make them usable by other people, but if you&#8217;ve got any problems or questions, post in the comments and we&#8217;ll try and help. There may be bugs in these, so let us know if you find any!</p>
<ul>
<li><a href="/downloads/textureatlas/Texture%20Atlas%20Generator.zip">Texture Atlas Generator</a></li>
<li><a href="/downloads/textureatlas/Texture%20Atlas%20-%20XNA.zip">XNA Runtime and Pipeline Libraries</a></li>
<li><a href="/downloads/textureatlas/Texture%20Atlas%20Runtime%20-%20iPhone.zip">iPhone Runtime</a> &#8211; Requires zlib and libpng</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.gogo-robot.com/2010/03/20/texture-atlas-sprite-sheet-generator/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Windows Phone 7 Flashlight (With SOS)</title>
		<link>http://www.gogo-robot.com/2010/03/19/windows-phone-7-flashlight-with-sos/</link>
		<comments>http://www.gogo-robot.com/2010/03/19/windows-phone-7-flashlight-with-sos/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 12:02:16 +0000</pubDate>
		<dc:creator>Rew</dc:creator>
				<category><![CDATA[Developer Blog]]></category>
		<category><![CDATA[windows phone 7]]></category>
		<category><![CDATA[xna]]></category>

		<guid isPermaLink="false">http://www.gogo-robot.com/?p=199</guid>
		<description><![CDATA[I tried posting this as a comment in reply to this post, but the code got mangled, so I&#8217;m posting it here graphics.GraphicsDevice.Clear&#40; /* Check for touch panel being pressed */ TouchPanel.GetState&#40;&#41;.Count == 0 ? /* Touch panel released, so reset the timer. This is stored in the target elapsed time, so we don't have [...]]]></description>
			<content:encoded><![CDATA[<p>I tried posting this as a comment in reply to <a href="http://codecube.net/2010/03/windows-phone-7-flashlight/">this post</a>, but the code got mangled, so I&#8217;m posting it here <img src='http://www.gogo-robot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">            graphics<span style="color: #008000;">.</span><span style="color: #0000FF;">GraphicsDevice</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Clear</span><span style="color: #008000;">&#40;</span>
                <span style="color: #008080; font-style: italic;">/* Check for touch panel being pressed */</span>
            TouchPanel<span style="color: #008000;">.</span><span style="color: #0000FF;">GetState</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span> <span style="color: #008000;">==</span> <span style="color: #FF0000;">0</span> <span style="color: #008000;">?</span>
                <span style="color: #008080; font-style: italic;">/* Touch panel released, so reset the timer. This is stored in the target elapsed time, so we don't have to create any variables :) We also turn off IsFixedTimeStep, so that TargetElapsedTime isn't used. */</span>
                <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IsFixedTimeStep</span> <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span> <span style="color: #008000;">=</span> TimeSpan<span style="color: #008000;">.</span><span style="color: #0000FF;">FromMilliseconds</span><span style="color: #008000;">&#40;</span>Math<span style="color: #008000;">.</span><span style="color: #0000FF;">Max</span><span style="color: #008000;">&#40;</span>1<span style="color: #008000;">.</span>0f, gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TotalMilliseconds</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">==</span> TimeSpan<span style="color: #008000;">.</span><span style="color: #0000FF;">Zero</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> Color<span style="color: #008000;">.</span><span style="color: #0000FF;">Gray</span> <span style="color: #008000;">:</span> Color<span style="color: #008000;">.</span><span style="color: #0000FF;">Gray</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">:</span>
                <span style="color: #008080; font-style: italic;">/* Touch panel pressed, so do SOS */</span>
                <span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">1</span> <span style="color: #008000;">?</span> Color<span style="color: #008000;">.</span><span style="color: #0000FF;">White</span> <span style="color: #008000;">:</span>
                <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&gt;=</span> <span style="color: #FF0000;">2</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">3</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> Color<span style="color: #008000;">.</span><span style="color: #0000FF;">White</span> <span style="color: #008000;">:</span>
                <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&gt;=</span> <span style="color: #FF0000;">4</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> Color<span style="color: #008000;">.</span><span style="color: #0000FF;">White</span> <span style="color: #008000;">:</span>
                <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&gt;=</span> <span style="color: #FF0000;">7</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">9</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> Color<span style="color: #008000;">.</span><span style="color: #0000FF;">White</span> <span style="color: #008000;">:</span>
                <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&gt;=</span> <span style="color: #FF0000;">10</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">12</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> Color<span style="color: #008000;">.</span><span style="color: #0000FF;">White</span> <span style="color: #008000;">:</span>
                <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&gt;=</span> <span style="color: #FF0000;">13</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">15</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> Color<span style="color: #008000;">.</span><span style="color: #0000FF;">White</span> <span style="color: #008000;">:</span>
                <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&gt;=</span> <span style="color: #FF0000;">17</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">18</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> Color<span style="color: #008000;">.</span><span style="color: #0000FF;">White</span> <span style="color: #008000;">:</span>
                <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&gt;=</span> <span style="color: #FF0000;">19</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">20</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> Color<span style="color: #008000;">.</span><span style="color: #0000FF;">White</span> <span style="color: #008000;">:</span>
                <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&gt;=</span> <span style="color: #FF0000;">21</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>gameTime<span style="color: #008000;">.</span><span style="color: #0000FF;">TotalGameTime</span> <span style="color: #008000;">-</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">TargetElapsedTime</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Seconds</span> <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">22</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">?</span> Color<span style="color: #008000;">.</span><span style="color: #0000FF;">White</span> <span style="color: #008000;">:</span>
                Color<span style="color: #008000;">.</span><span style="color: #0000FF;">Black</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.gogo-robot.com/2010/03/19/windows-phone-7-flashlight-with-sos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Converting a tile map into geometry</title>
		<link>http://www.gogo-robot.com/2010/02/01/converting-a-tile-map-into-geometry/</link>
		<comments>http://www.gogo-robot.com/2010/02/01/converting-a-tile-map-into-geometry/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 13:20:17 +0000</pubDate>
		<dc:creator>Rew</dc:creator>
				<category><![CDATA[Developer Blog]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[geometry]]></category>
		<category><![CDATA[tile]]></category>

		<guid isPermaLink="false">http://www.gogo-robot.com/?p=111</guid>
		<description><![CDATA[I recently needed to convert a tile map consisting of squares and triangles into chunks of geometry and after trying a couple of different approaches, I eventually settled on one which seems to work. I didn&#8217;t come across it anywhere else, so I thought I&#8217;d post it here in case anyone else is wanting to [...]]]></description>
			<content:encoded><![CDATA[<p>I recently needed to convert a tile map consisting of squares and triangles into chunks of geometry and after trying a couple of different approaches, I eventually settled on one which seems to work. I didn&#8217;t come across it anywhere else, so I thought I&#8217;d post it here in case anyone else is wanting to do something similar.</p>
<p><span id="more-111"></span></p>
<p>So, the problem is: Given a regular tile map, where each tile is either a square or a triangle taking up half of the square, generate sets of vertices which describe each &#8216;chunk&#8217; of geometry in the map. E.g.:</p>
<p style="text-align: center;"><img src="http://www.gogo-robot.com/wp-content/uploads/2010/01/TilesToGeom1.png" alt="Tiles To Geometry Fig. 1" title="Tiles To Geometry Fig. 1" width="640" height="224" class="alignnone size-full wp-image-114" /></p>
<p>The first method I tried was adapting <a href="http://en.wikipedia.org/wiki/Marching_squares">this method</a>, by representing each tile in a 2&#215;2 way, like so:</p>
<p style="text-align: center;"><img src="http://www.gogo-robot.com/wp-content/uploads/2010/01/TilesToGeom2.png" alt="Tiles To Geometry Fig. 2" title="Tiles To Geometry Fig. 2" width="160" height="112" class="alignnone size-full wp-image-117" /></p>
<p>Then performing the contour tracing algorithm in the link above, and removing every other point in the resulting list of points. At first it looked like this worked, but there were a couple of cases where a triangle was placed next to another triangle where the algorithm failed. <img src='http://www.gogo-robot.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>After thinking about it for a while, I came up with this method, which I&#8217;m pretty sure works, but if anyone can see any errors with it, please do let me know. I&#8217;ll give you the algorithm, then go through it in detail. The algorithm goes as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Pick a start tile
    Add the start tile to the open list
    Remove the tile from the tile map
    Add each of the tile's vertices to the vertex list
    Add each of the tile's edges to the edge list
    While the open list is not empty
        CurrentTile = Tile at the end of the open list
        NextTile = Tile in the &quot;forward&quot; direction of the current tile
        If NextTile exists and shares a common edge with the current shape
            Add NextTile to the open list
            Remove NextTile from the tile map
            Add NextTile's vertices to the vertex list (without creating duplicates)
            Generate an edge list for NextTile
            Remove edges that overlap from the main edge list and the edge list for NextTile
            Add the remaining edges from NextTile to the main edge list
        Else
            Move on to the next &quot;forward&quot; direction for CurrentTile
            If &quot;forward&quot; direction for CurrentTile = initial &quot;forward&quot; direction
                Remove CurrentTile from the open list
&nbsp;
Traverse the edge list and add the vertices that are used to the vertex list for your shape</pre></div></div>

<p>So, what does that all mean? Well, lets go through it step by step:</p>
<h2>Add the start tile to the open list</h2>
<p>The easiest way to search for a start tile is to do a row by row search. Start at 0,0 and scan along the first row, then the second and so on until you find an occupied tile. This is your start tile. The open list is a list of tiles currently being looked at. The start tile will be the first tile in this list.</p>
<h2>Remove the tile from the tile map</h2>
<p>Removing the tile from the tile map means that the algorithm will no longer visit them. Obviously, if you need your tile map after running the algorithm, create a copy of it <img src='http://www.gogo-robot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Add each of the tile&#8217;s vertices to the vertex list</h2>
<p>The vertex list stores each corner point that has been used by each tile. For the first tile, just add the world space corner points to the list.</p>
<h2>Add each of the tile&#8217;s edges to the edge list</h2>
<p>The edge list is an list of, you guessed it, edges! Each edge is a pair of indices into the vertex list. Note that edges should always be specified in the same winding order and should always start at the same corner. I.e. pick clockwise or counter-clockwise and use that for both the square and triangle tiles, like so:</p>
<p style="text-align: center;"><a href="http://www.gogo-robot.com/wp-content/uploads/2010/02/EdgesAndVerts.png"><img src="http://www.gogo-robot.com/wp-content/uploads/2010/02/EdgesAndVerts.png" alt="Edges and Vertices example" title="EdgesAndVerts" width="464" height="132" class="alignnone size-full wp-image-123" /></a></p>
<p>Notice on the last triangle that we started at the top left (as there is no vertex in the bottom left, and this would be the next one round in our clockwise winding order).</p>
<h2>While the open list is not empty</h2>
<p>I.e. While we&#8217;re still examining tiles for our current shape.</p>
<h2>CurrentTile = Tile at the end of the open list</h2>
<p>Set the current tile to the last tile added to the open list</p>
<h2>NextTile = Tile in the &#8220;forward&#8221; direction of the current tile</h2>
<p>Each tile in the open list maintains the direction of the neighbour that it is currently examining. Each time a tile is added to the open list, its &#8220;forward&#8221; direction (i.e. the direction in which to examine) is set to &#8220;up&#8221;. I just use an integer here, with the range 0 &#8211; 3, representing up, right, down and left, in that order. When we&#8217;re on a tile, we examine the neighbour in the tile&#8217;s &#8220;forward&#8221; direction, and pursue that path as far as possible. The next time the algorithm comes back to a tile, it rotates to the next &#8220;forward&#8221; direction and tries that path, until all four directions have been exhausted.</p>
<h2>If NextTile exists and shares a common edge with the current shape</h2>
<p>If there is a neighbour in our current tile&#8217;s &#8220;forward&#8221; direction, then we check to see if the neighbour and the current tile share common edges. One way to do this is to generate a list of edges for NextTile using the current vertex list. Any edges which contain vertices in the current vertex list will use the same vertex indices as the existing edges, but in reverse order (due to each tile having the same winding order), like so:</p>
<p style="text-align: center;"><a href="http://www.gogo-robot.com/wp-content/uploads/2010/02/WindingOrder.png"><img src="http://www.gogo-robot.com/wp-content/uploads/2010/02/WindingOrder.png" alt="Winding Order" title="WindingOrder" width="219" height="132" class="alignnone size-full wp-image-124" /></a></p>
<p>In the above image, the shared edge is V2 -> V3 for the left tile, and V3 -> V2 for the right tile.</p>
<h2>Add NextTile to the open list</h2>
<p>Add NextTile to the end of the open list, initialising its &#8220;forward&#8221; direction to 0 (up)</p>
<h2>Remove NextTile from the tile map</h2>
<p>Remove NextTile from the tile map so it is not revisited by the algorithm (except for when it is returned to by the open list).</p>
<h2>Add NextTile&#8217;s vertices to the vertex list (without creating duplicates)</h2>
<p>Add each world space vertex for the tile to the vertex list, but don&#8217;t create duplicates for vertices that are already in the vertex list.</p>
<h2>Generate an edge list for NextTile</h2>
<p>Generate a list of edges (remember, each edge is a pair of indices into the vertex list), using vertices from the vertex list.</p>
<h2>Remove edges that overlap from the main edge list and the edge list for NextTile</h2>
<p>Remove any edges that overlap from both the edge list that was just generated for NextTile, and the main edge list. Remember, neighbouring tiles with overlapping edges will specify the indices of the overlapping edge in opposite order from each other. I.e. If a tile has an edge V2 -> V3, and the neighbouring tile has an edge that shares these vertices, the neighbouring tile&#8217;s edge will be V3 -> V2. This is due to the winding order, as shown above.</p>
<h2>Add the remaining edges from NextTile to the main edge list</h2>
<p>Any edges that do not overlap can now be added to the main edge list</p>
<h2>Move on to the next &#8220;forward&#8221; direction for CurrentTile</h2>
<p>When you reach here, it means there are no tiles to check in the current direction, so we should rotate to look in the next direction. If you&#8217;re storing your &#8220;forward&#8221; direction as an integer, simply increment it.</p>
<h2>If &#8220;forward&#8221; direction for CurrentTile = initial &#8220;forward&#8221; direction</h2>
<p>This is a check to see if we&#8217;ve exhausted each of the four directions. The initial &#8220;forward&#8221; direction will be 4 if you&#8217;re representing directions as an integer in the range 0 &#8211; 3. If the &#8220;forward&#8221; direction reaches 4, it means we have tested each direction (0 &#8211; 3) and we are done with this tile.</p>
<h2>Remove CurrentTile from the open list</h2>
<p>As we are done with this tile, we can remove it from the open list.</p>
<p></p>
<p>So, after we&#8217;ve generated our edge list, we now need to traverse it. Simply start at the first edge and follow the trial of edges around the shape until you reach the start vertex again. E.g.: First edge: V0 -> V1, so add V0 and V1 to your shape, then search for an edge that starts at V1. Next edge: V1 -> V4, so add V4 to your shape and search for an edge that starts at V4, and so on, until you reach V0 again. You&#8217;ve now got a list of vertices that represent your shape.</p>
<p></p>
<p>After this, two possible further steps are to optimize your final list of vertices (i.e. remove co-linear ones, so you are only left with the corner vertices), and remove any tiles which are inside your shape (unless you want to create shapes within shapes). Note, that the final step will only produce the outline shape of an object, so will not handle holes in closed objects. You may be able to handle holes in closed objects by recursively performing the last step and removing edges from the final edge list as you visit them, until the list is empty. This should give you multiple shapes, the first being the outer shape and the rest being the holes inside the shape, but I haven&#8217;t really looked in to this that much, so it may not work <img src='http://www.gogo-robot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Here&#8217;s a little animation of the algorithm. The grey edges are overlapping ones that have been removed.</p>
<p style="text-align: center;"><a href="http://www.gogo-robot.com/wp-content/uploads/2010/02/GenerateTileGeomAnim.gif"><img src="http://www.gogo-robot.com/wp-content/uploads/2010/02/GenerateTileGeomAnim.gif" alt="Algorithm Animation" title="GenerateTileGeomAnim" width="208" height="192" class="alignnone size-full wp-image-131" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gogo-robot.com/2010/02/01/converting-a-tile-map-into-geometry/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Facebook Connect Dialog on iPhone</title>
		<link>http://www.gogo-robot.com/2010/01/10/facebook-connect-dialog-on-iphone/</link>
		<comments>http://www.gogo-robot.com/2010/01/10/facebook-connect-dialog-on-iphone/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 15:03:14 +0000</pubDate>
		<dc:creator>Rew</dc:creator>
				<category><![CDATA[Developer Blog]]></category>
		<category><![CDATA[Facebook Connect]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://www.gogo-robot.com/?p=75</guid>
		<description><![CDATA[A problem I keep having when adding Facebook Connect to iPhone applications is that sometimes the dialogs appear briefly then disappear. I keep forgetting why it is for a while, so I thought I&#8217;d post this to help anyone who is having a similar problem, and to remind myself about it so that maybe next [...]]]></description>
			<content:encoded><![CDATA[<p>A problem I keep having when adding Facebook Connect to iPhone applications is that sometimes the dialogs appear briefly then disappear. I keep forgetting why it is for a while, so I thought I&#8217;d post this to help anyone who is having a similar problem, and to remind myself about it so that maybe next time I won&#8217;t forget <img src='http://www.gogo-robot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-75"></span></p>
<p>Anyway, the problem is in the FBDialog.m file. There are a couple of lines that read:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">UIWindow<span style="color: #002200;">*</span> window <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span>.keyWindow;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>window<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    window <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span>.windows objectAtIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#91;</span>window addSubview<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>The problem comes when you try and show the Facebook dialog just after something other than the main window is the key window. This could happen if you&#8217;ve popped up a UIAlertView to ask if the user wants to publish to Facebook. The UIAlertView is the application&#8217;s key window and when you display your Facebook dialog, it adds itself as a subview of the UIAlertView (which is currently closing). So, your dialog will start to display, then when the UIAlertView finishes closing, it&#8217;ll disappear. The easy fix is to just change the FBDialog.m file so that it always uses the second line, and doesn&#8217;t try to use the keyWindow property:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">UIWindow<span style="color: #002200;">*</span> window <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span>.windows objectAtIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>window addSubview<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.gogo-robot.com/2010/01/10/facebook-connect-dialog-on-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The App Store Release Date</title>
		<link>http://www.gogo-robot.com/2009/10/05/the-app-store-release-date/</link>
		<comments>http://www.gogo-robot.com/2009/10/05/the-app-store-release-date/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 14:30:10 +0000</pubDate>
		<dc:creator>Rew</dc:creator>
				<category><![CDATA[Developer Blog]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://www.gogo-robot.com/?p=64</guid>
		<description><![CDATA[So I think I’ve finally figured out how you should handle the release date when you’re submitting your app. From what I can see, when your app gets approved, it gets the release date you set when you submitted, even if the date it gets approved is AFTER the release date. Consequently, when your app [...]]]></description>
			<content:encoded><![CDATA[<p>So I think I’ve finally figured out how you should handle the release date when you’re submitting your app. From what I can see, when your app gets approved, it gets the release date you set when you submitted, even if the date it gets approved is AFTER the release date. Consequently, when your app appears on the App Store, it’s already a few pages down when sorted by release date. Not good <img src='http://www.gogo-robot.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p><span id="more-64"></span></p>
<p>So, I’m guessing you have to set your release date way off into the future (because you have no idea how long it’s going to take Apple to approve your app), so that when it’s approved, you can bring it forward to the current date and it’ll be top of the new releases list. I’m going to be trying this with our next iPhone game, so I’ll keep you posted how it turns out. The one potential problem is that if Apple looks at the release date to determine when they’ll test your app, it might be a while before it gets tested.</p>
<p></p>
<p><strong>Update</strong>: Apparently, from reading around, the release date will be listed as the earliest of (i) the date you set when submitting, and (ii) the date it is approved by Apple. So even if you set your availability date to some distant future date, then set it to something sensible when it’s released, it’ll be down in iTunes as the date it was approved. So I guess the moral of the story is this:</p>
<p></p>
<p><em>When submitting your app to the App Store, set the availability date to a month or two ahead (and remember to update it if you have to re-submit or if it takes Apple ages to approve it), so that it’s always ahead of the date it gets approved. Then, once it’s approved, set the release date to the date it was approved (so it actually appears on the App Store). You need to set it as soon as you receive the &#8220;Ready for sale&#8221; e-mail from apple, and remember to set the availability date to the date that Apple sent the e-mail (remember to take into account the time difference between you and Apple in Cupertino). E.g. If you receive the e-mail in the early hours of Tuesday morning, and you&#8217;re in the UK, then Apple will have sent the e-mail on Monday (their time), so your availability date should be Monday.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gogo-robot.com/2009/10/05/the-app-store-release-date/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Two awkward things about iPhone development</title>
		<link>http://www.gogo-robot.com/2009/06/07/two-awkward-things-about-iphone-development/</link>
		<comments>http://www.gogo-robot.com/2009/06/07/two-awkward-things-about-iphone-development/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 14:36:16 +0000</pubDate>
		<dc:creator>Rew</dc:creator>
				<category><![CDATA[Developer Blog]]></category>
		<category><![CDATA[Galactic Aquarium]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://www.gogo-robot.com/?p=69</guid>
		<description><![CDATA[I’m currently in the process of porting The Galactic Aquarium to the iPhone now that the 360 version is done. While doing this, I’ve come across a couple of awkward points to do with UIKit on the iPhone, so I thought I’d share how I got around them. The first is using a custom font [...]]]></description>
			<content:encoded><![CDATA[<p>I’m currently in the process of porting The <a href="http://www.gogo-robot.com/categories/games/">Galactic Aquarium</a> to the iPhone now that the 360 version is done. While doing this, I’ve come across a couple of awkward points to do with UIKit on the iPhone, so I thought I’d share how I got around them.</p>
<p><span id="more-69"></span></p>
<p>The first is using a custom font with a UILabel. Although you can set the font property of a UILabel, the only fonts you can create are system fonts. What you have to do is subclass the UILabel class and override the <em>– (void)drawTextInRect:(CGRect)rect</em> method with your own implementation.</p>
<p></p>
<p>First things first though, you need to load in your font. <strong>Note: With this method, you need to distribute the .ttf file with your app. Make sure this is ok in the font’s license.</strong></p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Get the path to our custom font and create a data provider.</span>
<span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>fontPath <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSBundle</span> mainBundle<span style="color: #002200;">&#93;</span> pathForResource<span style="color: #002200;">:</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;FontFilename&quot;</span> ofType<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;ttf&quot;</span><span style="color: #002200;">&#93;</span>;
CGDataProviderRef fontDataProvider <span style="color: #002200;">=</span> CGDataProviderCreateWithFilename<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>fontPath UTF8String<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Create the font with the data provider, then release the data provider.</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Note: s_CustomFont is a static variable, not an instance variable</span>
<span style="color: #11740a; font-style: italic;">// so that it can be shared between all instances of the custom font UILabel class</span>
s_CustomFont <span style="color: #002200;">=</span> CGFontCreateWithDataProvider<span style="color: #002200;">&#40;</span>fontDataProvider<span style="color: #002200;">&#41;</span>;
CGDataProviderRelease<span style="color: #002200;">&#40;</span>fontDataProvider<span style="color: #002200;">&#41;</span>;</pre></div></div>

<p>Now that you’ve got the font loaded in, you need to draw your text with it. Unfortunately, you can’t just set the font then call <em>[super drawTextInRect: rect]</em>. This is because there are actually two different methods of drawing fonts in Quartz. <em>CGContextShowText</em> displays a string of text using the currently <strong>selected</strong> font. You select the font using <em>CGContextSelectFont</em>, but this function is only capable of selecting a built in system font. The other option is to use <em>CGContextShowGlyphs</em> and <em>CGContextSetFont</em>. Notice that’s <strong>Set</strong>Font and not <strong>Select</strong>Font.</p>
<p></p>
<p>The SelectFont / ShowText combination uses the name of the font to look up the font data and the glyph mapping table in the system. The glyph mapping table is used by the font renderering routines to match up glyphs from the font with characters in your string. There’s no way to programatically set the glyph mapping table, which is why there are the two methods of drawing text.</p>
<p></p>
<p>When using the SetFont / ShowGlyphs method, you need to manually convert the characters in your string to glyph indices in the font. Fortunately, this generally works out pretty easily, which we’ll see later.</p>
<p></p>
<p>Now that we have our font loaded in, we can write our custom drawTextInRect function. So, first thing’s first, you need to set the font to use:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">CGContextSetFont<span style="color: #002200;">&#40;</span>UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>, s_CustomFont<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// We need to tell the system which font size to use too</span>
<span style="color: #a61390;">float</span> FontSize <span style="color: #002200;">=</span> <span style="color: #2400d9;">18</span>; <span style="color: #11740a; font-style: italic;">// 18-pt font size</span>
CGContextSetFontSize<span style="color: #002200;">&#40;</span>UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>, FontSize<span style="color: #002200;">&#41;</span>;</pre></div></div>

<p>Then we need to convert our string to glyph indices. Like I said before, this mostly works out quite easily. Usually, you just need to offset the character index by a “magic number”, and most of the time this number turns out to be -29:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Convert the text to glyphs</span>
<span style="color: #a61390;">int</span> StringLength <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self.text length<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Make sure you remember to free these after rendering</span>
CGGlyph<span style="color: #002200;">*</span> Glyphs <span style="color: #002200;">=</span> <span style="color: #a61390;">malloc</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>CGGlyph<span style="color: #002200;">&#41;</span> <span style="color: #002200;">*</span> StringLength<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">char</span><span style="color: #002200;">*</span> Chars <span style="color: #002200;">=</span> <span style="color: #a61390;">malloc</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">char</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">*</span> <span style="color: #002200;">&#40;</span>StringLength <span style="color: #002200;">+</span> <span style="color: #2400d9;">1</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Convert characters to glyph indices</span>
<span style="color: #002200;">&#91;</span>self.text getCString<span style="color: #002200;">:</span> Chars maxLength<span style="color: #002200;">:</span> <span style="color: #002200;">&#40;</span>StringLength <span style="color: #002200;">+</span> <span style="color: #2400d9;">1</span><span style="color: #002200;">&#41;</span> encoding<span style="color: #002200;">:</span> NSASCIIStringEncoding<span style="color: #002200;">&#93;</span>;
<span style="color: #a61390;">for</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> CurrentChar <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>; CurrentChar <span style="color: #002200;">&amp;</span>lt; StringLength; <span style="color: #002200;">++</span>CurrentChar<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#123;</span>
    Glyphs<span style="color: #002200;">&#91;</span>CurrentChar<span style="color: #002200;">&#93;</span> <span style="color: #002200;">=</span> Chars<span style="color: #002200;">&#91;</span>CurrentChar<span style="color: #002200;">&#93;</span> <span style="color: #002200;">-</span> <span style="color: #2400d9;">29</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>One thing to consider here is that any new line escape sequences will end up with some really high glyph index (as CGGlyph is just an unsigned short). But you have to handle new lines manually anyway, so it shouldn’t be too bad.</p>
<p></p>
<p>Finally, we can draw our text. You need to setup your text matrix and text position before drawing the text, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Set the text matrix, otherwise it draws upside down</span>
CGAffineTransform TextMatrix <span style="color: #002200;">=</span> CGAffineTransformIdentity;
&nbsp;
TextMatrix.d <span style="color: #002200;">=</span> <span style="color: #002200;">-</span><span style="color: #2400d9;">1</span>;
CGContextSetTextMatrix<span style="color: #002200;">&#40;</span>UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>, TextMatrix<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Set the text position - Remember, 0, 0 is the top left of the text's draw rectangle, not the screen</span>
CGContextSetTextPosition<span style="color: #002200;">&#40;</span>UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>, <span style="color: #2400d9;">0</span>, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;</pre></div></div>

<p>Note that <em>CGContextSetTextPosition</em> sets the same translation values that the translation component of the text matrix sets, so in the above case it’s obsolete. But when you start adding multi-line and alignment support, it’s cleaner to just set the text matrix once and then just use <em>CGContextSetTextPosition</em> to set the position.</p>
<p></p>
<p>Now just draw your glyphs:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">CGContextShowGlyphs<span style="color: #002200;">&#40;</span>UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>, Glyphs, StringLength<span style="color: #002200;">&#41;</span>;</pre></div></div>

<p>So there’s our basic custom font drawing routing. If I recall correctly, it’ll crash as soon as you have a newline in your string, because it tries to just use a glyph that isn’t there. What you have to do is, during renderering, scan along your glyphs until there is a new line, draw the glyphs up until the new line, then start again from just after the new line.</p>
<p></p>
<p>You can also implement alignment and word wrapping. To do this, you need to be able to measure the string, so here’s how you do that:</p>
<p></p>
<p>After a call to <em>CGContextShowGlyphs</em>, the current text position is updated and can be retrieved like this:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">CGPoint EndPoint <span style="color: #002200;">=</span> CGContextGetTextPosition<span style="color: #002200;">&#40;</span>UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;</pre></div></div>

<p>So EndPoint.x is the length of your string (assuming your initial text position was at 0, 0). You can prevent Quartz from actually doing any drawing while you’re measuring the string’s length by setting the text drawing mode to invisible:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">CGContextSetTextDrawingMode<span style="color: #002200;">&#40;</span>UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>, kCGTextInvisible<span style="color: #002200;">&#41;</span>;</pre></div></div>

<p>Remember to set your drawing mode and text position back to normal when you want to actually draw your text:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">CGContextSetTextDrawingMode<span style="color: #002200;">&#40;</span>UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>, kCGTextFill<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// You can also set to the text colour to the UILabel's textColor property</span>
CGContextSetFillColorWithColor<span style="color: #002200;">&#40;</span>UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>, self.textColor.CGColor<span style="color: #002200;">&#41;</span>;</pre></div></div>

<p>Now that you have the text size, you can use the UILabel’s <em>textAlignment</em> property to determine how to align your text when you actually draw it. Word wrapping can be achieved using a standard word wrapping algorithm. Just keep drawing glyphs until EndPoint.x is greater than self.frame.size.width. Then you know you’ve exceeded the frame and need to word wrap. So then you can jump back to the previous word, reset the text position to 0, 0 and continue on. It’s best to store each line length during your measuring stage so that they can be used to align the text during drawing.</p>
<p></p>
<p>One problem I haven’t yet figured out is the height of a line. At the moment I’m just using FontSize * 1.2, which seems to work OK for the font I’ve tried this on. I’m sure there’s probably some better way to do it, but I haven’t looked into it too much.</p>
<p></p>
<p>You can use the measuring technique to automatically size the height of your custom UILabel, to prevent it from being clipped (seeing as how you can’t actually see your custom font in Interface Builder). I added a new function to my custom font label class to calculate the height of the word wrapped text. I then use the height to set the height of the frame. This does mean that I have to set the frame’s width, call the function then set the frame’s height to the returned value. It also means you have to make sure the graphics context is correctly set up during the heigh measuring function (which it probably won’t be if it’s called from outside the drawTextInRect function. The easiest way to do this is to create a temporary graphics context, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">CGSize ContextSize;
ContextSize.width <span style="color: #002200;">=</span> <span style="color: #2400d9;">480</span>;
ContextSize.height <span style="color: #002200;">=</span> <span style="color: #2400d9;">320</span>;
UIGraphicsBeginImageContext<span style="color: #002200;">&#40;</span>ContextSize<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Measure the string's height</span>
&nbsp;
.....
&nbsp;
UIGraphicsEndImageContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;</pre></div></div>

<p>So there you have it. That’s how I’ve got my custom font UILabels to be used.</p>
<p></p>
<p>The other awkward thing is a lot simpler. I didn’t realise how long that last one was going to be <img src='http://www.gogo-robot.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p></p>
<p>The problem arises when you want to display a modal view controller straight after another one has been dismissed. It seems the best place to show the second one is in the <em>viewDidDisappear</em> function of the first UIViewController. However, calling <em>presentModalViewController</em> on the parent UIViewController from this function doesn’t work (nothing seems to happen). I’m guessing it’s because the modal view controller for the parent view controller is still pointing to the one that’s just disappeared, and that this gets cleaned up after <em>viewDidDisappear</em> is called, so any new modal view controller you set in <em>viewDidDisappear</em> is reset straight after the function returns (because the parent view controller is still in the process of cleaning up the first one). The solution is to use the performSelector function on the parent view controller with a delay of 0:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>self.parentViewController performSelector<span style="color: #002200;">:</span> <span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>myDisplayNextModalViewControllerFunction<span style="color: #002200;">&#41;</span> withObject<span style="color: #002200;">:</span> <span style="color: #a61390;">nil</span> afterDelay<span style="color: #002200;">:</span> <span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>The delay of 0 doesn’t mean that the selector is performed straight away. Because of the order of events in the run loop, the selector will be performed after the parent view controller has fully dismissed its modal view controller, so the next one will display fine.</p>
<p></p>
<p>Hope this helps <img src='http://www.gogo-robot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.gogo-robot.com/2009/06/07/two-awkward-things-about-iphone-development/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

