<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
    xmlns:admin="http://webns.net/mvcb/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:content="http://purl.org/rss/1.0/modules/content/">

    <channel>
    
    <title>Rawkes &#45; Captain&#39;s Blog</title>
    <link>http://rawkes.com/</link>
    <description></description>
    <dc:language>en</dc:language>
    <dc:creator>rob.hawkes@gmail.com</dc:creator>
    <dc:rights>Copyright 2010</dc:rights>
    <dc:date>2010-03-07T13:00:44+00:00</dc:date>
    

    <item>
      <title>Basic Gameplay Features Added to Augmented Reality Game</title>
      <link>http://rawkes.com/blog/2010/03/07/basic-gameplay-features-added-to-augmented-reality-game</link>
      <guid>http://rawkes.com/blog/2010/03/07/basic-gameplay-features-added-to-augmented-reality-game</guid>
      <content:encoded><![CDATA[<p>There has been a lot of progress since the last update. Most noticeable is the addition of gameplay features; objects you have to avoid, basic character health, and win/lose scenarios.</p>

<figure>
<object width="620" height="349"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9977439&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9977439&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="620" height="349"></embed></object>
</figure>

<p>As you can see, 3D models are yet to be added to the game. For now, placeholder objects are being utilised. The objects you can currently see are: walls [blue], fire [red], wasabi [green], and the finish line [orange].</p>

<p>Different objects have a different effect on the character, ranging from a change in movement to outright death. Further objects will be added to the game as well as refinement of the interaction with current objects.</p>]]></content:encoded>
      <dc:subject></dc:subject>
      <dc:date>2010-03-07T13:00:44+00:00</dc:date>
    </item>

    <item>
      <title>Stop Highlighting the Gender Difference</title>
      <link>http://rawkes.com/blog/2010/02/13/stop-highlighting-the-gender-difference</link>
      <guid>http://rawkes.com/blog/2010/02/13/stop-highlighting-the-gender-difference</guid>
      <content:encoded><![CDATA[<p>Boagworld celebrated its 200th show yesterday. A live podcast was put on throughout the day to commemorate this event. Many members of the Web industry took part including the likes of Andy Clarke and Rachel Andrews, both respected professionals.</p>

<p>Unfortunately, activities in a live chat-room for the event have overshadowed the otherwise successful day. These events came in the form of sexist comments against some of the female guests on the show. The comments have sparked quite <a href="http://www.sazzy.co.uk/2010/02/dont-you-dare/">intense retaliation</a> from <a href="http://www.rachelandrew.co.uk/archives/2010/02/13/women-and-the-backchannel/">those involved</a> and the Web community at large.</p>

<p>I would like to state right now that the actions of some people in the chat-room were childish, unwarranted, and something I don’t condone in any way. However, this whole situation is very interesting, both with the commenters and with the overall response to the comments. There is much to learn from these events.</p>

<p>This issue has been discussed at length on Twitter and the general consensus is that these comments manifested simply because the chat-room was anonymous. Because there was no physical tie between comments and real people, it meant that anything could be said without fear of attribution. It was a free-for-all where the strongest feelings could be vented with ease, wether they are warranted or not.</p>

<p>An unfortunate aspect of crowds is that as soon as one feeling is made public, anyone else with those feelings feels better about joining in; becoming one of the mob. As this mob grows the feelings get stronger and stronger until they lose all focus and erupt into personal attacks. This is bad.</p>

<p>On the flip-side, most of these comments were undoubtably made by young and immature people who have a bad case of jealousy. Or at least you’d hope that is the case! The reason this didn’t happen to any of the male guests is that the majority of this industry, and in turn the chat-room, is male. I would bet money on 100% of the bad comments coming from males. But why the attack on females? Well, because when you’re jealous the best way to feel better is bring the other person down, at least in your own mind. The only way they could do that was by attacking the biggest difference; gender. I'm by no means an expert of psychology, but this is all pretty obvious stuff.</p>

<p>I'd like to stress again that I'm not condoning what happened, I simply believe a little understanding of the issue will prevent the community coming to knee-jerk conclusions. It seems to me that the response to the comments has turned into a defensive backlash about how woman deserve to be in the Web industry and how hard they’ve worked for it. Why has such a small number of anonymous comments required this much defending? Especially if the majority of the industry supports equal rights.</p>

<p>I can’t see equality being reached if there is a backlash every time a comment is made seemingly against said equality. If you highlight the difference then the difference will persist. It's a never-ending loop that must be broken somewhere along the line. Of course, this post is part of that loop, but I feel it's place is warranted by highlighting the need to break said loop.</p>

<p>In conclusion, none of this would’ve happened if users of the chat-room were required to register, attributing a real name and email in the process. A sense of responsibility results once a physical link is made between the user and his comments. The user must think carefully about the impact of their words before joining the crowd. I believe a majority, if not all, of the comments yesterday would not have happened if this simple requirement was in place.</p>
]]></content:encoded>
      <dc:subject></dc:subject>
      <dc:date>2010-02-13T14:36:10+00:00</dc:date>
    </item>

    <item>
      <title>The Virtual Revolution</title>
      <link>http://rawkes.com/blog/2010/02/06/the-virtual-revolution</link>
      <guid>http://rawkes.com/blog/2010/02/06/the-virtual-revolution</guid>
      <content:encoded><![CDATA[<p>As a student of interactive media I have an inherent, sometimes obsessive interest in the history and theory of the web. To my absolute delight, the BBC is currently airing a documentary series covering the last 20 years of the web and, as they put it, exploring how it's reshaping almost every aspect of our lives. It's fantastic stuff I tell you!</p>

<p>The <a href="http://www.bbc.co.uk/programmes/b00qn37q">first episode of The Virtual Revolution</a> dropped last Saturday and gave an informative overview into the Internet's history and the resulting issues with it's fundamental feature, openness.</p>

<p>This evening brought with it <a href="http://www.bbc.co.uk/programmes/b00qsbvv">episode 2</a> which focussed on how the freedom given by the open Internet can prove damaging, and how some entities are trying to restrict that freedom. The result is an online battle between sophisticated defence mechanisms [the censorship], users [the free people], and technology providing a means of bypassing said defences. Censorship is an area of the web that is very young and one that will prove increasingly important to everyone who uses it, regardless of location.</p>

<p>So far the series has been insightful but most importantly, because of it's airtime on BBC 2, it is allowing the general public to learn about the hidden issues that affect them in so many ways. Unfortunately the web and the technology behind it is still seen as something that only geeks are allowed to know about. I hope this series will change that.</p>

<p>There has already been quite heated debate on social networks about the topics covered, and this is a good thing. Previously such topics would be unknown to most and left alone to do as they wish. Maybe this new audience will be moved to do something about the most important issues, maybe not. What matters is that the magic of the web is being laid bare in format that all can understand.</p>]]></content:encoded>
      <dc:subject></dc:subject>
      <dc:date>2010-02-06T23:00:09+00:00</dc:date>
    </item>

    <item>
      <title>Tracking Multiple Augmented Reality Markers with FLARManager and Papervision</title>
      <link>http://rawkes.com/blog/2010/01/26/tracking-multiple-augmented-reality-markers-flarmanager-and-papervision</link>
      <guid>http://rawkes.com/blog/2010/01/26/tracking-multiple-augmented-reality-markers-flarmanager-and-papervision</guid>
      <content:encoded><![CDATA[<p>A lucky few already know that I'm currently working on an augmented reality (AR) project, due to be complete in March this year. The project is that of a game which revolves around physical interaction via AR. However, I'll bore you with the details another day as right now we're here for something else.</p>

<p>If you haven't already seen what we'll be making today then have a quick gander at this video I made and all will become clear.</p>

<figure>
    <object width="620" height="466"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8214397&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8214397&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="620" height="466"></embed></object>
</figure>

<h2>Prerequisites</h2>

<p>This isn't a tutorial for beginners to AR or ActionScript so I'd advise you read up elsewhere and get comfortable with the basics before you tackle multiple markers.</p>

<p>Ideally you need to:</p>

<ul>
<li>Have a basic understanding of object oriented programming</li>
<li>Be comfortable working with ActionScript</li>
</ul>

<p>I'm using <a href="http://labs.adobe.com/technologies/FlashBuilder4/">Flash Builder</a> as my IDE of choice for this tutorial but feel free to use whatever you're most comfortable in. I've included a version in <a href="#download">the source files</a> that can be developed in Flash CS4, it's separate because you need to tweak a couple of files to get it working.</p>

<p>As well as basic AR tracking we'll learn how to add some Papervision3D objects into the fray.</p>

<p>We'll be using the following external resources:</p>

<ul>
<li><a href="http://words.transmote.com/wp/flarmanager/">FLARManager</a> &mdash; From which a lot of code for this tutorial comes from</li>
<li><a href="http://blog.papervision3D.org/">Papervision3D</a></li>
</ul>

<h2>Solving the problem</h2>

<p>One of the most difficult issues I encountered during early development with AR is how to track multiple markers at once. Thanks to frameworks like FLARToolkit and FLARManager, tracking a single marker is relatively simple as you can code knowing that you'll only ever need to deal with one marker at a time. Your application inherits higher level of complexity when you want to reliably handle and track a dynamic amount of markers. Fortunately, if I do my job right, it will become dead easy after you've read this tutorial.</p>

<p>The solution lies in finding a way to store references of all the markers in view, or in use. From here we can refer to the stored reference whenever we want to update a marker. If we want to remove a marker from the system all we need to do is remove the reference, amongst a couple other things, but we'll get onto the nitty gritty further on. Enter the <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/Dictionary.html">ActionScript Dictionary class</a>.</p>

<p>Before we continue, let's take a moment to understand what the Dictionary class does and why we want to use it over common functionality like arrays and objects.</p>

<p>In brief, an array in ActionScript is only useful if you want numerical keys to reference the stored data. Although an array <em>can</em> use named keys in ActionScript, that is strings as keys, you wouldn't be able to utilise any of the built-in array functions. Objects on the other hand are built to use string keys which allow for more meaningful naming of properties. Dictionary objects are useful because they use objects themselves as keys. Besides this, the most important thing to understand about Dictionary objects are that they use strict equality [<code>===</code>] when referencing a key that is an object. The killer feature of the Dictionary object is that you can use the keys as you would a normal object, referencing properties and the like.</p>

<p>It may sound confusing, and it is, but there is a difference between Objects and Dictionaries. You could achieve the same functionality within this tutorial using Objects but I'll be using Dictionaries because of the strict referencing and the fact we can store objects within the keys. If you're still lost I'd advise reading through <a href="http://www.gskinner.com/blog/archives/2006/07/as3_dictionary.html">this article on the Dictionary class by Grant Skinner</a>.</p>

<h2>Setting up the project</h2>

<p>The first thing we need to do is set up the core Flash Builder project. Now, we could do this manually by creating a new project and importing all the relevant files and packages into the right places, but we won't be doing that. Instead I've already created a basic project and we'll be importing that to save some time, you'll need to <a href="#download">download and unpack the source files</a> in preparation.</p>

<p>In Flash Builder, or your IDE of choice, you need to go to <strong>File</strong>&rarr;<strong>Import</strong>&rarr;<strong>Flash Builder Project&hellip;</strong>, or likewise.</p>

<figure>
    <img src="http://rawkes.com/media/tracking-multiple-augmented-reality-markers-flarmanager-and-papervision/dialogue-window.jpg" width="620" height="465" alt="Flash Builder Project dialogue window">
    <p class="legend">Flash Builder Project dialogue window</p>
</figure>

<p>A dialogue window will spring up with a few options. Make sure <strong>Project folder</strong> is selected and then click browse, selecting the <strong>Multiple Markers Project</strong> folder from the source files you just downloaded. Once you've selected the project folder click finish and let the IDE do its thang. You should now have a new project showing up on the left of the IDE. These instructions may differ slightly for other IDEs, if nothing happened for you then you'll need to find out how to specifically import existing projects into your chosen IDE.</p>

<p>"Wow, this is a lot of effort just to begin", I hear you say. You're right, I reply, but we're nearly done. Last but not least is to open up the main ActionScript file, which is neatly tucked away within our new project folder. Double click on the folder and you'll be presented with a bunch more folders. Double click on <strong>src</strong>, then <strong>(default package)</strong>, then <strong>Multiple_Markers.as</strong>. Bang. We're in business.</p>

<figure>
    <img src="http://rawkes.com/media/tracking-multiple-augmented-reality-markers-flarmanager-and-papervision/project-directory-tree.jpg" width="620" height="470" alt="Flash Builder Project directory tree">
    <p class="legend">Flash Builder Project directory tree</p>
</figure>

<p>The ActionScript file should've opened up on the right, if not then have a poke around for the file as it should be in there somewhere. You'll notice that I've already imported the required packages, but feel free to remove any you don't want if you're deviating from this tutorial. I've also included the following self-explanatory code to format the outputted SWF file when we're finished:</p>

<pre><code>[SWF(width="640", height="480", frameRate="25", backgroundColor="#000000")]
</code></pre>

<p>All our code is going to go inside the <code>Multiple_Markers</code> class declaration:</p>

<pre><code>public class Multiple_Markers extends Sprite {

}
</code></pre>

<p>That's enough setting up, let's crack on with what you came for.</p>

<h2>Augmenting reality</h2>

<p>Our system revolves around the FLARManager package, a wrapper of sorts that gives us access to all the exciting AR doo-dahs. We'll begin by prepping the system so it's ready to make reality awesome. Insert the following inside the <code>Multiple_Markers</code> class:</p>

<pre><code>/* FLARManager pointer */
private var fm:FLARManager;

/* Constructor method */
public function Multiple_Markers() {
    /* Run augmented reality initialisation */
    this.initFLAR();
}
</code></pre>

<p>First we're setting the FLARManager variable <code>fm</code>  that will hold our FLARManager object when we initialise it later. Next is the class constructor function that will run automatically when the system loads. Inside the constructor we're requesting the method <code>initFLAR()</code> which will hold all the code to initialise FLARManager. Let's create that method now by adding the following below the constructor method:</p>

<pre><code>/* Augmented reality initialisation */
private function initFLAR():void {
    /* Initialise FLARManager */
    this.fm = new FLARManager("flarConfig.xml");

    /* Event listener for when a new marker is recognised */
    fm.addEventListener(FLARMarkerEvent.MARKER_ADDED, this.onAdded);
    /* Event listener for when a marker is removed */
    fm.addEventListener(FLARMarkerEvent.MARKER_REMOVED, this.onRemoved);
    /* Event listener for when the FLARManager object has loaded */
    fm.addEventListener(Event.INIT, this.onFlarManagerLoad);

    /* Display webcam */
    this.addChild(Sprite(fm.flarSource));
}
</code></pre>

<p>This really isn't anything complicated, all we've done is initialise a FLARManager object and create a bunch of event listeners that look out for; when an AR marker is detected, when an AR marker is removed, and when the FLARManager object has finished initialising. The last line uses our FLARManager object, referred from now as <code>fm</code>, to activate the user's webcam by adding it to the main stage.</p>

<p>For the meantime let's create some empty methods to keep the event listeners happy. Add the following underneath the <code>initFLAR</code> method:</p>

<pre><code>/* Run if FLARManager object has loaded */
private function onFlarManagerLoad(e:Event):void {
    /* Remove event listener so this method doesn't run again */
    this.fm.removeEventListener(Event.INIT, this.onFlarManagerLoad);
}

/* Run when a new marker is recognised */
private function onAdded(e:FLARMarkerEvent):void {

}
/* Run when a marker is removed */
private function onRemoved(e:FLARMarkerEvent):void {

}
</code></pre>

<p>It's important to note that the first line in <code>onFlarManagerLoad</code> removes the <code>fm</code> initialisation event listener so it can only run once. The two marker listeners are passed a marker event object as an argument, which we'll use later to access detailed information about each marker.</p>

<p>By now we've created the underlying functionality for FLARManager, and if you run the system (⌘+F11 in Flash Builder) then your webcam should display in a Flash Player window. If not, then something went wrong and you'll need to have a look through the code again. If it still isn't working then post a message in the comments below.</p>

<p>The eagle-eyed of you will have noticed that I didn't talk about the <code>flarConfig.xml</code> argument in the <code>fm</code> initialisation. I have good reason as it's something that deserves some focus, of which it will now receive.</p>

<h2>All about flarConfig.xml</h2>

<p>If you look inside the <strong>src</strong> folder and double click on <strong>flarConfig.xml</strong> you'll be presented with the configuration settings for the <code>fm</code> object. The settings are split into 4 main areas; video source settings, FLARManager settings, camera parameters, and AR patterns. Transmote does a good job at <a href="http://words.transmote.com/wp/flarmanager/flarmanager-documentation/">explaining everything in detail in the official documentation</a> so I'll be brief.</p>

<h3>Video source settings</h3>

<p>These are the settings which will define the dimensions that video is captured [<code>sourceWidth</code> &amp; <code>sourceHeight</code>], dimensions that video is displayed [<code>displayWidth</code> &amp; <code>displayHeight</code>], the framerate that video is captured at, and the amount of downsampling (scaling down) that the captured video receives before being processed. None of these settings affect the dimensions of the SWF window, those are changed by editing the line above the <code>Multiple_Markers</code> class declaration.</p>

<h3>FLARManager settings</h3>

<p>Slightly more advanced, these settings define if the video feed should be mirrored [<code>mirrorDisplay</code>], the amount of smoothing to give the AR marker animations [<code>smoothing</code>], the class to use for smoothing [<code>smoother</code>], and the accuracy of marker detection in changing light conditions [<code>thresholdAdapter</code>].</p>

<h3>Camera parameters</h3>

<p>A file has been provided by FLARManager, or more accurately by FLARToolkit, to compensate for webcam distortion and other gloriously exciting discrepancies. Point <code>&lt;cameraParamsFile&gt;</code> to the location of this file, which has already been done if you're using the source files I provided.</p>

<h3>AR patterns</h3>

<p>An array [<code>&lt;patterns&gt;</code>] of pattern files [<code>&lt;pattern&gt;</code>] that we want to detect. 6 pattern files have already been provided for you and can be printed from the <strong>Patterns</strong> folder in the unpacked source file I provided.</p>

<h2>Bring on the markers</h2>

<p>Now we're ready to start dealing with markers. Start by declaring our storage objects for the patterns and marker containers, of which we'll get to shortly. Add the following below <code>private var fm:FLARManager;</code> in the head of our class:</p>

<pre><code>/* Vector storing references to all markers on screen, grouped by pattern id */
private var markersByPatternId:Vector.&lt;Vector.&lt;FLARMarker&gt;&gt;;
/* Dictionary storing references to marker containers, indexed by relevant marker object */
private var containersByMarker:Dictionary;
</code></pre>

<p><code>markersByPatternId</code> is a Vector which is an array in which all the elements have the same data type. In our case we are creating a multi-dimensional Vector that we're saying must contain Vector objects, that in turn must contain FLARMarker objects. By restricting the data type like this we can rest assured that we'll be dealing exclusively with data we want.</p>

<p><code>containersByMarker</code> is a Dictionary object which we'll be using later to manage the Papervision containers for each marker. They will make plenty of sense later so forget about them for now.</p>

<p>We can now finish off the <code>initFLAR</code> method by inserting the following underneath <code>this.fm = new FLARManager("flarConfig.xml");</code>:</p>

<pre><code>/* Temporary declaration of how many patterns are being used */ 
var numPatterns:int = 6;
/* Initialise markerByPatternId vector object */
this.markersByPatternId = new Vector.&lt;Vector.&lt;FLARMarker&gt;&gt;(numPatterns, true);
/* Loop through each pattern */
while (numPatterns--) {
    /* Add empty Vector to each pattern */
    this.markersByPatternId[numPatterns] = new Vector.&lt;FLARMarker&gt;();
}

/* Initialise empty containersByMarker dictionary object */
this.containersByMarker = new Dictionary(true);
</code></pre>

<p><code>numPatterns</code> is an integer that tells us how many patterns we declared in the configuration file. On the next line we define <code>markersByPatternId</code> to create a Vector object with 6 [<code>numPatterns</code>] empty slots and use <code>true</code> to make sure this value can't be changed dynamically in the future. The while statement loops through the Vector object we just created and adds another empty Vector to each of the 6 elements (one for each pattern). We didn't set a limit or boolean value this time because we don't know how many markers we'll be tracking. Finally we define <code>containersByMarker</code> as an empty Dictionary object and enable garbage collection on the included objects by including the <code>true</code> argument. It's not important to know what the garbage collection is doing right now, I just thought it best to highlight that it's enabled.</p>

<p>While we're at it we can finish off the two marker event listeners. First off add the following to our <code>onAdded</code> method:</p>

<pre><code>/* Run method to add a new marker */
this.addMarker(e.marker);   
</code></pre>

<p>And the following to the <code>onRemoved</code> method:</p>

<pre><code>/* Run method to remove a marker */
this.removeMarker(e.marker);
</code></pre>

<p>All that's happening here is a call to the <code>addMarker</code> and <code>removeMarker</code> methods with the added/removed marker object attached. It's by sheer coincidence that we're going to create these two methods right now.</p>

<p>Insert the following below the <code>onRemoved</code> method:</p>

<pre><code>/* Add a new marker to the system */
private function addMarker(marker:FLARMarker):void {
    /* Store reference to list of existing markers with same pattern id */
    var markerList:Vector.&lt;FLARMarker&gt; = this.markersByPatternId[marker.patternId];
    /* Add new marker to the list */
    markerList.push(marker);
}
</code></pre>

<p>This method will provide the core functionality for adding new markers to the system. Right now it's set up to store a reference to each marker the system detects. By passing a marker object to <code>addMarker</code> we're able to access a variety of information about the marker in question. We use this information to find out the marker's pattern id [<code>marker.patternId</code>] or, in layman's terms, the numerical position of the pattern in the configuration file pattern list (a number from 0 to 5, remember that arrays are 0 indexed).</p>

<p>Now that we know the pattern id we can access the relevant <code>markersByPatternId</code> Vector object for that pattern, from the 6 we created earlier, and store a reference in the temporary <code>markerList</code> variable. All the last line does is <code>push</code> [add] a reference to the new marker onto the end of the <code>markerList</code> Vector object. When populated, the <code>markersByPatternId</code> Vector object will contain references to every marker, grouped by their pattern id [0-5]. It's important to get your head around how this works so take a moment to read over everything again if necessary.</p>

<p>Add the <code>removeMarker</code> method directly underneath the <code>addMarker</code> method:</p>

<pre><code>/* Remove a marker from the system */
private function removeMarker(marker:FLARMarker):void {
    /* Store reference to list of existing markers with same pattern id */
    var markerList:Vector.&lt;FLARMarker&gt; = this.markersByPatternId[marker.patternId];
    /* Find index value of marker to be removed */
    var markerIndex:uint = markerList.indexOf(marker);
    /* If marker exists in markerList */
    if (markerIndex != -1) {
        /* Remove marker from markersByPatternId */
        markerList.splice(markerIndex, 1);
    }
}
</code></pre>

<p>You'll recognise the first line is pretty much the same as in <code>addMarker</code>, referencing the <code>markersByPatternId</code> Vector object for the selected marker's pattern id. To remove the referenced marker from our Vector object we first need to find out the position [index] of the marker within the Vector. To do so we utilise the built-in <code>indexOf</code> method and pass it the marker we're looking for. In return we'll be given an integer, either the index of the marker (if it's found), or <code>-1</code> if the marker can't be found. This result is then stored in <code>matkerIndex</code> so we can use it later.</p>

<p>Welcome to later. Now we have the result of our marker search we run a basic <code>if</code> statement to check if we actually found a marker. If so then we <code>splice</code> [remove] the marker from the <code>markerList</code> Vector object. Job done. Feel free to run the system to make sure there are no errors. You could print some markers and add a basic trace message, like below, if you want to see an output when you introduce a marker to the display:</p>

<pre><code>trace("Added marker with pattern id: "+marker.patternId);
</code></pre>

<p>Congratulations, you've successfully implemented a fully functioning AR system that detects multiple markers. However, it's mighty boring as it stands. How about we create something nice to look at? Agreed? Fantastic.</p>

<h2>Entering the third dimension</h2>

<p>Flash was never really built to handle much more than 2D graphics, and rolling our own 3D engine would be way beyond the scope of this tutorial. Luckily for us a group of bright young developers put together Papervision, an incredibly awesome 3D engine that does everything we need and more.</p>

<p>There are a few bits and pieces that need addressing before we can start breaking down the second dimension. First up is setting some variables that we're going to be using for Papervision later on. Insert the following below <code>private var fm:FLARManager;</code> in the head of our class:</p>

<pre><code>/* Papervision Scene3D pointer */
private var scene3D:Scene3D;
/* Papervision Viewport3D pointer */
private var viewport3D:Viewport3D;
/* FLARToolkit FLARCamera3D pointer */ 
private var camera3D:FLARCamera3D;
/* Papervision PointLight3D pointer */
private var pointLight3D:PointLight3D;
/* Papervision render engine pointer */
private var lre:LazyRenderEngine;
</code></pre>

<p>Variables should be pretty standard to you by now so we'll cut to the chase and take a moment to go through what the referenced Papervision classes actually do.</p>

<ul>
<li><code>Scene3D</code> is a container for the 3D environment and is where all our 3D objects will be placed.</li>
<li><code>Viewport3D</code> is literally a window into the 3D environment.</li>
<li><code>FLARCamera3D</code> is a special FLARToolkit class that extends the Papervision <code>Camera3D</code> class, accounting for webcam distortion. It's purpose is to let us move around, with the 3D environment changing depending on our position. Just like when you move around, the objects your looking at will change their size and perspective.</li>
<li><code>PointLight3D</code> is a light which points in one direction, it illuminates the <code>Scene3D</code> so we can create shadows.</li>
<li><code>LazyRenderEngine</code> puts everything together. It displays the <code>Scene3D</code> environment as seen through the <code>Viewport3D</code> window from the <code>FLARCamera3D</code> position.</li>
</ul>

<p>Insert the following method call after the event listener in <code>onFlarManagerLoad</code>:</p>

<pre><code>/* Run Papervision initialisation method */
this.initPaperVision();
</code></pre>

<p>We'll create that method call now. Add the following below our <code>removeMarker</code> method:</p>

<pre><code>/* Papervision initialisation method */
private function initPaperVision():void {
    /* Initialise a new Papervision scene */
    this.scene3D = new Scene3D();
    /* Initialise a new FLARCamera3D object to enable full AR goodness */
    this.camera3D = new FLARCamera3D(this.fm.cameraParams);

    /* Define a new Papervision viewport object */
    this.viewport3D = new Viewport3D(640, 480, true);
    /* Add viewport to the main scene */
    this.addChild(this.viewport3D);

    /* Define a new Papervision point light */
    this.pointLight3D = new PointLight3D(true, false);
    /* Set light position */
    this.pointLight3D.x = 1000;
    this.pointLight3D.y = 1000;
    this.pointLight3D.z = -1000;
    /* Add light to the Papervision scene */
    this.scene3D.addChild(pointLight3D);

    /* Initialise the Papervision render engine */
    this.lre = new LazyRenderEngine(this.scene3D, this.camera3D, this.viewport3D);

    /* Create event listner to run a method on each frame */
    this.addEventListener(Event.ENTER_FRAME, this.onEnterFrame);
}
</code></pre>

<p>There is nothing scary happening here. In the first line we are defining our <code>Scene3D</code> object. In the second we define our <code>FLARCamera3D</code> object and pass it a reference to the camera parameters file we talked about in the FLARManager configuration. The same goes for the third line where we define our <code>Viewport3D</code> object and make it the same dimensions as the SWF, also setting the third argument to <code>true</code> so it scales with the main stage. On the next line we add the <code>Viewport3D</code> object to the main stage.</p>

<p>On the fifth line we define our <code>PointLight3D</code> object and set the first argument to <code>true</code> so the light is visible. In the lines that follow we set the position of the light in 3D space, <code>z</code> being the depth. You can set these value as you wish, there is no specific reason to use 1000. After setting the positions we add the light to the <code>scene3D</code> object so it illuminates whatever 3D objects we decide to put in later.</p>

<p>Next we define the Papervision rendering engine and pass it our <code>scene3D</code>, <code>camera3D</code>, and <code>viewport3D</code> objects as arguments. There are a few rendering engines to choose from but I'm used to the <code>LazyRenderingEngine</code> so that's what we're going with here.</p>

<p>Currently our system won't display anything and will only run once, for a successful animation we need to update our 3D scene on every frame. To do that we create a new event listener on the main stage that calls the <code>onEnterFrame</code> method at the beginning of every new frame (30 frames per second).</p>

<p>Now would definitely be a good time to create that <code>onEnterFrame</code> method we just declared. Insert the following below the <code>initPaperVision</code> method:</p>

<pre><code>/* Method to run on each frame */
private function onEnterFrame(e:Event):void {
    /* Render the Papervision scene */
    this.lre.render();
}
</code></pre>

<p>What this method does is call the <code>LazyRenderEngine</code>'s <code>render</code> method on every single frame, which will update the 3D scene and thus create the illusion of movement. However, if you run the system right now you'll see we don't have anything to display yet. The fact that nothing went wrong tells you that the Papervision environment is working, but that's not much fun so let's attach some 3D cubes to our markers.</p>

<h2>Visualising the markers</h2>

<p>This is easily the largest and most complex section of the tutorial so it's worth taking a breather before we continue. Go on, I'm not joking around here. Done? Good. Set your tea down on the desk and let's well and truly shatter the second dimension.</p>

<p>Add the following underneath our <code>onEnterFrame</code> method, at the very end of the class:</p>

<pre><code>/* Get colour values dependent on pattern id */
private function getColorByPatternId(patternId:int, shaded:Boolean = false):Number {
    switch (patternId) {
        case 0:
            if (!shaded)
                return 0xFF1919;
            return 0x730000;
        case 1:
            if (!shaded)
                return 0xFF19E8;
            return 0x730067;
        case 2:
            if (!shaded)
                return 0x9E19FF;
            return 0x420073;
        case 3:
            if (!shaded)
                return 0x192EFF;
            return 0x000A73;
        case 4:
            if (!shaded)
                return 0x1996FF;
            return 0x003E73;
        case 5:
            if (!shaded)
                return 0x19FDFF;
            return 0x007273;
        default:
            if (!shaded)
                return 0xCCCCCC;
            return 0x666666;
    }
}
</code></pre>

<p><code>getColorByPatternId</code> is a helper method that we'll be using to grab the colour values for each of our 6 patterns. By assigning a separate colour to each pattern we can easily distinguish between different markers on the screen. I've included some extra functionality to give a darker shade if we set the <code>shaded</code> boolean to false. Let's forget about <code>getColorByPatternId</code> for now as it will make more sense when we come to use it.</p>

<p>The process going on when creating a 3D cube, and most other objects, in Papervision is actually a pretty simple one:</p>

<ol>
<li>Create a 3D container for the object</li>
<li>Define materials for the object</li>
<li>Create the object and add the materials</li>
<li>Add the object to the 3D container</li>
<li>Add the 3D container to the Papervision scene</li>
<li>Render the scene (usually done elsewhere in the system)</li>
</ol>

<p>As you can see it's not exactly rocket science to get 3D objects into Flash with Papervision. Most of the steps mentioned are literally one line of code, 2 at most. All the code we're using for creating the 3D cubes will be done in <code>addMarker</code>, so that's where we'll go now. Add the following at the end of the method (before the last curly brace):</p>

<pre><code>/* Initialise the marker container object */
var container:DisplayObject3D = new DisplayObject3D();

/* Prepare material to be used by the Papervision cube based on pattern id */
var flatShaderMat:FlatShadeMaterial = new FlatShadeMaterial(this.pointLight3D, this.getColorByPatternId(marker.patternId), this.getColorByPatternId(marker.patternId, true));
/* Add material to all sides of the cube */
var cubeMaterials:MaterialsList = new MaterialsList({all: flatShaderMat});

/* Initialise the cube with material and set dimensions of all sides to 40 */
var cube:Cube = new Cube(cubeMaterials, 40, 40, 40);
</code></pre>

<p>This code should make some sense if you read it through like the process I defined above. In the first line we're creating a new <code>DisplayObject3D</code>, our 3D container for the object. The next two lines define the materials we want to use on each cube. I'll focus on this a little as it's important to grasp how materials work in Papervision.</p>

<p>Adding materials to an object in Papervision is usually a one or two step process, depending on how messy you want the code to be; first defining the material you want to use then, second, adding that material to the object. Some objects require multiple materials, like a cube, but the premise is the same; materials should be seen as separate to the objects they're being added to. The great thing about Papervision is that you have <a href="http://papervision3d.googlecode.com/svn/trunk/as3/trunk/docs/org/papervision3d/materials/package-detail.html">a whole variety of material types</a> at your disposal. Whether you want block colours or a movie, there are material types to handle it, and if you want to get advanced you have <a href="http://papervision3d.googlecode.com/svn/trunk/as3/trunk/docs/org/papervision3d/materials/shadematerials/package-detail.html">a selection of shaded material types</a> to use as well. I won't go into detail about how to define each type of material, but the method we use for the cube is very similar, if not a little more complex.</p>

<p>In our code, on the second uncommented line, we define the type of material we're after; a <code>FlatShadeMaterial</code>. This material type reacts to light in the 3D scene and shades certain areas. To define the <code>FlatShadeMaterial</code> we pass the <code>pointLight3D</code> from our Papervision scene, along with the colours we want to use for lit, and unlit sides. Instead of using arbitrary colours we grab the <code>patternId</code> of our marker and use that to get the relevant colour from the <code>getColorByPatternId</code> method we created earlier, passing a boolean value of <code>true</code> to the second request so we get the relevant shaded colour instead. I told you it'd make more sense when we came to use it.</p>

<p>As we're create a cube we need to define materials for all of the 6 faces. To do this we define a <code>MaterialsList</code> object which we use to assign materials to each side. The parameters of the <code>MaterialsList</code> object allow us to assign a different material for each side. For our purposes a single material for all sides is just fine, which is why we're using the <code>all</code> parameter.</p>

<p>Now we have the materials sorted out we can move onto step 3 and actually create the object, our cube. To do so we define a <code>Cube</code> object, passing in the <code>MaterialsList</code> object we just created, as well as the dimensions [width, depth, height] of the cube (you can actually make it a cuboid shape if you wish). That's all for creating a cube, it really is as easy as that. The cube isn't actually visible yet as we haven't added it to the Papervision scene, so the next few lines of code will prepare us to do that. Add the following below the cube definition:</p>

<pre><code>/* Shift cube upwards so it sits on top of paper instead of being cut half-way */
cube.z = 0.5 * 40;

/* Add finished cube object to marker container */
container.addChild(cube);
/* Add marker container to the Papervision scene */
this.scene3D.addChild(container);

/* Add marker container to containersByMarker Dictionary object */
this.containersByMarker[marker] = container;
</code></pre>

<p>There is nothing crazy going on here. First we change the Z position of the cube to raise it by half it's height. We do this because the registration point of a cube in Papervision, the origin from which movement and rotation is made, is slap bang inside the core, right in the middle of the cube. If we left the Z position as it was then the cube would be sitting as if it was sliced in half, so we raise it up by half to make it sit on the bottom surface.</p>

<p>On the next two lines we add the cube as a child of the <code>DisplayObject3D</code>, our 3D container, and then add that container as a child of the Papervision scene. This is vital as without adding the cube to the scene it will never be rendered.</p>

<p>It's all well and good adding the cube and container to the 3D scene, but without a method of tracking each object it would be a nightmare to manipulate or remove them in the future. This is why we created the <code>containersByMarker</code> Dictionary object previously. The last line of code above adds our newly created container to that object, referenced by the marker we're adding the cube to.</p>

<p>That's it for creating the cubes, now we move on to removing them. Add the following at the end of the <code>removeMarker</code> method:</p>

<pre><code>/* Store reference to marker container from containersByMarker Dictionary object */
var container:DisplayObject3D = this.containersByMarker[marker];
/* If a container exists */
if (container) {
    /* Remove container from the Papervision scene */
    this.scene3D.removeChild(container);
}
/* Remove container reference from containersByMarker Dictionary object */
delete this.containersByMarker[marker];
</code></pre>

<p>This is basically a reversal of the additions we made when adding a cube. In the first line we create a reference to the 3D container stored in the <code>containersByMarker</code> Dictionary object for the current marker (see how useful it is now?). From here we run a simple validation check to make sure a container actually exists and, if so, remove it from the Papervision scene. Finally we delete any reference to the container in the Dictionary object. All gone!</p>

<p>We're so nearly there, all that's left is to create the method that will run every frame updating the whole system. Below the <code>onEnterFrame</code> method, add a new method called <code>updateMarkers</code> with the following code inside:</p>

<pre><code>/* Update markers method */
private function updateMarkers():void {
    /* Store reference to amount of patterns being tracked */
    var i:int = this.markersByPatternId.length;
    /* Store reference to list of existing markers */
    var markerList:Vector.&lt;FLARMarker&gt;;
    /* Empty marker variable */
    var marker:FLARMarker;
    /* Empty container variable */
    var container:DisplayObject3D;
    /* Empty integer */
    var j:int;

    /* Loop through all tracked patterns */
    while (i--) {

    }
}
</code></pre>

<p>Integral to the update method is a <code>while</code> statement that loops through all the AR patterns we want to track. Before we delve into the loop we need to set up a few variables:</p>

<ul>
<li><code>i</code> refers to the length [number of] AR patterns we want to track</li>
<li><code>markerList</code> defines an empty <code>Vector</code> that will hold <code>FLARMarker</code> objects</li>
<li><code>marker</code> defines a <code>FLARMarker</code> object that will refer to the current marker</li>
<li><code>container</code> defines a <code>DisplayObject3D</code> that will refer to the current 3D container</li>
<li><code>j</code> defines an integer that we'll use further within the loop</li>
</ul>

<p>Let's tackle the loop now. Add the following inside the <code>while</code> statement:</p>

<pre><code>/* Store reference to all markers with this pattern id */
markerList = this.markersByPatternId&#91;i];
/* Amount of markers with this pattern */
j = markerList.length;
/* Loop through markers with this pattern */
while (j--) {
    /* Store reference to current marker */
    marker = markerList[j];

    /* Find reference to marker container in containersByMarker Dictionary object */
    container = this.containersByMarker[marker];
    /* Transform container to new position in 3d space */
    container.transform = FLARPVGeomUtils.convertFLARMatrixToPVMatrix(marker.transformMatrix);
}
</code></pre>

<p>There is only one line here which is new to use, but we'll leave that until last. First off we grab an array of markers being stored in <code>this.markersByPatternId</code> for the current pattern id [<code>i</code>] and add it to the <code>markerList</code> variable we defined previously. From here we find out how many markers being tracked, the <code>length</code>, and store that value in the variable <code>j</code>. To loop through each marker we set up a new <code>while</code> statement using <code>j</code>. In each iteration of the marker loop we grab a reference to the current marker from <code>markerList</code> and store it in the <code>marker</code> variable. In turn we then use <code>marker</code> to retrieve the relevant 3D container from the <code>containersByMarker</code> Dictionary.</p>

<p>Finally, and I know you've been waiting for this moment, we update the position of the container relative to the AR marker being held up. To do this we use a rather nifty method provided by FLARManager called <code>convertFLARMatrixToPVMatrix</code>. What this method does it take the FLARMarker transformation matrix, the size, rotation and position, of the marker, and convert it into a Papervision transformation matrix. All that's left is to assign that converted matrix to the <code>transform</code> property of the 3D container and it will match the position and orientation of the AR marker. Pretty cool if I do say so myself.</p>

<p>Now, there is no use having an method to update the markers if we don't use it anywhere, so add the following call above <code>this.lre.render()</code> in the <code>onEnterFrame</code> method:</p>

<pre><code>/* Run method to update markers */
this.updateMarkers();
</code></pre>

<p>Now would be a good time to save, grab one of the AR markers, and run the system to check it works. If you see a cube pop up over your marker then congratulations, you've just created a fully functioning augmented reality system with Papervision. Over. Out. Finished. Finito. Completed.</p>

<h2>Rounding up what's been covered</h2>

<p>We certainly learnt a lot in this tutorial, with particular focus on FLARManager and Papervision. We learnt:</p>

<ul>
<li>About the Dictionary and Vector classes in ActionScript</li>
<li>How to implement basic AR support in ActionScript</li>
<li>How to create basic 3D objects in Papervision</li>
<li>How to impress your friends with pure awesomeness</li>
</ul>

<p>Ok, so the last one is a bit extravagant but I'm yet to find someone who doesn't stare at my computer screen when I'm working on AR in the library. Annoying? Perhaps. Cool points? Definitely.</p>

<h2>Taking this further</h2>

<p>I've given you a firm understanding of the basics and a platform to launch yourself into the exciting depths of AR. What happens next is up to you, but here are a few ideas:</p>

<ul>
<li>Adding a tween to the cubes to animate them when they're created</li>
<li>Animating the cubes so they constantly rotate on the spot</li>
<li>Replacing the cubes with something more exciting</li>
<li>Implementing collision detection between the cubes [advanced]</li>
</ul>

<p>If you do decide to take this further, add a link in the comments as I'd love to see.</p>

<a name="download"></a>

<h2>Source files</h2>

<p>All the source files referenced in this tutorial can be <a href="http://rawkes.com/media/tracking-multiple-augmented-reality-markers-flarmanager-and-papervision/Multiple Markers Source Code.zip">downloaded under a Creative Commons Attribution-Non-Commercial-Share Alike license</a> <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/80x15.png" /></a>.</p>]]></content:encoded>
      <dc:subject></dc:subject>
      <dc:date>2010-01-26T18:03:46+00:00</dc:date>
    </item>

    <item>
      <title>3D to 2D Grid Mapping with Augmented Reality [Video]</title>
      <link>http://rawkes.com/blog/2010/01/24/3d-to-2d-grid-mapping-with-augmented-reality</link>
      <guid>http://rawkes.com/blog/2010/01/24/3d-to-2d-grid-mapping-with-augmented-reality</guid>
      <content:encoded><![CDATA[<p>Integral to the AR game is it's grid environment, which controls the dimensions, orientation and other game-wide settings.</p>

<p>Another important function of the grid is to track and manipulate the location of items within the game world. This video shows early development of a system whereby interaction in the 3D world is tracked and translated into a 2D format.</p>

<p>When this system is fully functional, all objects in the game will be aware of not only their own location but that of other objects in the vicinity.</p>

<figure>
<object width="620" height="349"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8948685&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8948685&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="620" height="349"></embed></object>
</figure>

<p>Hot on the heels on the grid mapping demonstation comes fully-fledged AR marker mapping. In a nutshell the system can track the 2D position of a marker in relation to a 3D object and project that position onto a map for better visualisation.</p>

<figure>
<object width="620" height="349"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8950139&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8950139&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="620" height="349"></embed></object>
</figure>

<p>This dynamic tracking moves us a step closer to manipulating objects within the game environment via physical AR markers.</p>
]]></content:encoded>
      <dc:subject></dc:subject>
      <dc:date>2010-01-24T16:49:08+00:00</dc:date>
    </item>

    <item>
      <title>The Best Business Card in the World</title>
      <link>http://rawkes.com/blog/2010/01/17/the-best-business-card-in-the-world</link>
      <guid>http://rawkes.com/blog/2010/01/17/the-best-business-card-in-the-world</guid>
      <content:encoded><![CDATA[<p>I always feel a little useless at conferences and geek meet-ups because I don't have any business cards to give out. All I see around me is a blur of movement as cards are being transferred from one iPhone toting creative to another. Where's the love for Rawkes, ey?</p>

<p>Well, I've put my foot down. Enough is enough. It's now time for Rawkes to join in the fun and have some business cards of its own. Coincidently this decision happened at around the same time <a href="http://moo.com">MOO</a> decided to give me 50 business cards for free. Result!</p>

<p>So, with Photoshop in one hand and a cup of tea in the other, I got to work creating what can quite simply be called the most amazing business card in the entire world. Seriously.</p>

<p>I believe now would be a good time to stop waffling, so let me leave you with some images of said world-beating business cards. Perhaps you'll receive one of them in the future if you're lucky enough to bump into me on my travels.</p>

<figure>
    <img src="http://rawkes.com/media/images/2010/01/17/Business-Card-Front.jpg" width="620" height="416" alt="Front design for the Rawkes business card">
    <p class="legend">Front design for the Rawkes business card</p>
</figure>

<figure>
    <img src="http://rawkes.com/media/images/2010/01/17/Business-Card-Back.jpg" width="620" height="416" alt="Rear design for the Rawkes business card">
    <p class="legend">Rear design for the Rawkes business card</p>
</figure>]]></content:encoded>
      <dc:subject></dc:subject>
      <dc:date>2010-01-17T15:16:33+00:00</dc:date>
    </item>

    <item>
      <title>Grid Logic in Augmented Reality [Video]</title>
      <link>http://rawkes.com/blog/2010/01/16/grid-logic-in-augmented-reality-video</link>
      <guid>http://rawkes.com/blog/2010/01/16/grid-logic-in-augmented-reality-video</guid>
      <content:encoded><![CDATA[<p>An integral part of the augmented reality game I'm working on is the logic behind the scenes. This video shows very early development of this logic, in particularly the grid-based system that will be used to calculate positioning and ensure reliable interaction from the player. In the real game the grid would not look like this.</p>

<figure>
    <object width="620" height="465"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8760450&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8760450&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="620" height="465"></embed></object>
</figure>

<p>Further development of the grid logic for the augmented reality game includes a feature to completely remove the grid marker without removing the Papervision model. By removing the marker used for the grid/game environment, further markers can be added and manipulated without accidentally affecting the grid. The grid marker can be reintroduced at a later stage to update the position of the existing grid.</p>

<figure>
    <object width="620" height="349"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8780319&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8780319&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="620" height="349"></embed></object>
</figure>

<p>From here I'll be implementing further code to calculate relative positioning between dynamic markers and the grid, particularly the grid segment that each marker resides in.</p>]]></content:encoded>
      <dc:subject></dc:subject>
      <dc:date>2010-01-16T16:53:01+00:00</dc:date>
    </item>

    <item>
      <title>2009: In Review</title>
      <link>http://rawkes.com/blog/2010/01/13/2009-in-review</link>
      <guid>http://rawkes.com/blog/2010/01/13/2009-in-review</guid>
      <content:encoded><![CDATA[<p>My head is filled with fond memories of the millennium's first decade, mainly because I was a young whippersnapper of just 13 when it started. One of the most important things to happen in those years was the discovery of my passion for web design and development. In 10 years I've transformed from a blithering, spotty teenage novice to a competent and knowledgeable adult; from knowing absolutely nothing about HTML and design to knowing HTML, CSS, JavaScript, ActionScript, amongst countless other languages and theory. Let's just say the naughties have been kind to me; through hard work mainly, but also through a couple of fortunate and timely opportunities.</p>

<h2>The most awesome year by far</h2>

<p>2009 in particular has been memorable for many reasons, most notably for the sheer amount of new stuff that now clutters the inner realms of my cranium. University took up most of my life during the year and the rest of the time was spent slaving away on the <a href="http://rawkes.com/blog/2009/11/28/welcome-to-the-future-of-rawkes">new version of Rawkes</a>, <a href="http://rawkes.com/blog/2009/09/14/5-steps-to-innovation-my-experience-at-redweb">working for the lovely people at Redweb</a>, <a href="http://rawkes.com/blog/2009/12/11/an-insight-into-the-html-5-canvas-element">experimenting with canvas</a>, <a href="http://www.thewebdesignblog.co.uk/interviews/interview-with-web-developer-rob-hawkes/">being interviewed</a>&hellip; <a href="http://inspirebit.com/2009/11/10-questions-for-rob-hawkes/">twice</a>, uncovering <a href="http://rawkes.com/blog/2009/12/22/introducing-arduino-electronics-made-easy">the world of Arduino electronics</a>, and <a href="http://rawkes.com/blog/2009/12/01/my-involvement-in-redwebs-spirit-of-christmas-2009">measuring how festive the world was during Christmas</a>.</p>

<p>Here's just a glimpse of some of my most profound achievements of 2009:</p>

<p><img src="http://rawkes.com/media/images/2010/01/13/2009-statistics.png" width="620" height="420" alt="Extremely important statistics from 2009"></p>

<h2>Plans for twenty ten</h2>

<p>The last decade was good and, if I've anything to do with it, the next decade will be even better. It's still early days for me, especially considering I'm still in education and not settled into a career path yet. The next 10 years will bring graduation, hopefully, a serious career choice, possibly even fame? Actually, fame can go find someone else&mdash;I like my relatively private life.</p>

<p>However, none of this will happen if don't knuckle down and keep at it. I'm not getting any younger! With that in mind I've put together a wish-list of sorts for what I'd like to achieve in 2010:</p>

<ul>
<li>Release <del><a href="http://rawkes.com/blog/2009/12/14/factored-canvas-application-is-now-open-source">5</a></del> <ins>4</ins> open-source projects</li>
<li>Write 2 decent guest posts for other blogs</li>
<li>Produce an iPhone application</li>
<li>Make something big with Arduino</li>
<li>Write 5 articles relating to interesting media theory</li>
<li>Choose something profound for my third-year major project</li>
<li>Tackle a fascinating topic for my dissertation</li>
<li>Learn and actually use Git properly</li>
</ul>

<p>We'll see how they all pan out this time next year. I'm quietly confident that I can achieve everything on the list if I keep at it.</p>

<p>I'm looking forward to what the future holds, both for me and for technology and the internet as a whole. We live in exciting times with surprises around every corner. I can't wait!</p>]]></content:encoded>
      <dc:subject></dc:subject>
      <dc:date>2010-01-13T21:32:11+00:00</dc:date>
    </item>

    <item>
      <title>Introducing Arduino: Electronics Made Easy</title>
      <link>http://rawkes.com/blog/2009/12/22/introducing-arduino-electronics-made-easy</link>
      <guid>http://rawkes.com/blog/2009/12/22/introducing-arduino-electronics-made-easy</guid>
      <content:encoded><![CDATA[<p>Arduino. If you're like me when I first saw that word then you'll be thinking something along the lines of, "what are you on about you crazy person?". To be honest I'm still not entirely sure how to pronounce it, I believe it's ar-do-ee-no. Regardless, all you need to know is that it's a word you'll be hearing a lot of in the near future, even if that's all from my mouth alone.</p>

<h2>Fantastic. But what is it exactly?</h2>

<blockquote>
  <p>Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. It's intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments.</p>
  
  <p><cite class="caption">Official description &mdash; Arduino.cc</cite></p>
</blockquote>

<p>Put simply, Arduino has been created as an inexpensive way of making electronics available to designers and programmers at large. No longer do you need to waste money on a degree, or have a brain the size of a planet, the only requirements are a desire to learn and an ounce of patience. It would help to have a bit of programming experience but it isn't required.</p>

<figure>
    <img src="http://rawkes.com/media/images/2009/12/13/arduino-diecimila.jpg" width="620" height="442" alt="Arduino Diecimila board">
    <p class="legend">Arduino Diecimila board &mdash; by Randomskk</p>
</figure>

<p>Making electronics simple is achieved through code via a framework of sorts. At the core of any Arduino project is physical board, or PCB if you know the lingo, on which the code is uploaded to from your computer. The board comes with a variety of basic features that allow you to connect individual components, upload code via USB, and extend the board with plugins called 'shields'. By removing the need for soldering and by allowing control via upload-able code, you're able to make changes quickly and often without fear of breaking anything. The fancy name for this procedure is rapid prototyping.</p>

<p>All code is written in the open source <a href="http://arduino.cc/en/Reference/HomePage">Arduino programming language</a> through the Arduino IDE, a special text-editor that allows you to send code to the board. The IDE is based on the one used for <a href="http://www.processing.org/">Processing</a> so you'll feel comfortable if you've used Processing in the past, if not then I can assure you it's pretty easy to use. In a nutshell, the code, or sketch, is used to manipulate connected components, both inputs [sensors] and outputs [servos, displays, etc]. If you've used a web-based programming language before then think of reading input values as like dealing with user-submitted data, and outputting as echoing, or printing, data to the browser.</p>

<h2>Endless possibilities</h2>

<p>Being open source and inherently easy to use makes Arduino an extremely powerful and exciting platform. I would try and list all of its possible uses but quite simply I'd run out of space, there are literally an endless amount of things you can do with it. The beauty of the platform is that all the hard stuff, the core electronics, are done for you. If you only want to turn a light on and off then you'll need a couple of components [an LED, a resistor, and some wires] and a few lines of code. On the flip-side you could make something that talks to Twitter and manipulates an object in the physical world, this would obviously take more lines of code but the electronics would still be relatively minor in comparison to working without Arduino.</p>

<p>Here are just a few things you can achieve with Arduino:</p>

<ul>
<li>Manipulating lights [LEDs]</li>
<li>Making physical objects move [servos]</li>
<li>Using sensors to trigger actions [heat, light, movement, etc.]</li>
<li>Connecting to the internet
<ul><li>Reading data [Twitter, RSS, XML, etc.]</li>
<li>Writing data [Triggering scripts, etc.]</li></ul></li>
<li>Being location aware [Using a GPS shield]</li>
</ul>

<h2>Some prerequisites</h2>

<p>A few bits and pieces are needed before you can become an Arduino master, essentially a board and a few other components so you can actually do something interesting. I've listed my essentials below and also included a few useful components that'll come in handy, some places sell complete beginner kits that include everything you'll need for basic projects. You'll also find a list of my favourite shops that sell Arduino goodies.</p>

<h3>Essential components</h3>

<ul>
<li>Arduino board (I usually go for the Duemilanove)</li>
<li>USB cable</li>
<li>Electonics breadboard (no, not the wooden thing you cut a loaf on)</li>
<li>Jumper wires</li>
</ul>

<h3>Useful to have around</h3>

<ul>
<li>LEDs</li>
<li>Resistors</li>
<li>Servos</li>
</ul>

<h3>Where to buy Arduino gear (UK only)</h3>

<ul>
<li><a href="http://www.oomlout.co.uk">Oomlout</a> (My top choice)</li>
<li><a href="http://tinkerit.myshopify.com/collections/arduino">Tinker Tools</a></li>
<li><a href="http://www.coolcomponents.co.uk/catalog/index.php?cPath=50">Cool Components</a></li>
</ul>

<h3>Installing the IDE and USB drivers</h3>

<p>Before you can begin coding you need to install the Arduino IDE and USB drivers. The whole process is pretty straightforward and you can find instructions for <a href="http://arduino.cc/en/Guide/Windows">Windows</a>, <a href="http://arduino.cc/en/Guide/MacOSX">Mac OS X</a>, and <a href="http://www.arduino.cc/playground/Learning/Linux">Linux</a>, on the official website.</p>

<h2>Conquering the basics</h2>

<p>So you have an Arduino board, some components, and all the necessary software installed. Now all you need is a brief understanding of the code and you're good to go.</p>

<h3>Programming syntax</h3>

<p>If you've any previous programming experience then learning the Arduino syntax will be water off your back. In essence the syntax is just like the majority of languages out there; you end lines with semi-colons, have conditional [if] statements, functions, variables, and the like. The main elements unique to Arduino are:</p>

<ul>
<li><code>pinMode()</code>&mdash;Sets a pin [component] on the Arduino board as an input [to be read from] or output [to be written to]</li>
<li><code>digitalRead()</code>&mdash;Read the value of a pin [component]</li>
<li><code>digitalWrite()</code>&mdash;Write a value to a pin [component]</li>
<li><code>delay()</code>&mdash;Pause for a designated amount of time</li>
<li><code>setup()</code>&mdash;Called once when the Arduino starts</li>
<li><code>loop()</code>&mdash;Called recursively </li>
</ul>

<p>I'll be covering the syntax in more detail in another entry but for now you can find all the <a href="http://arduino.cc/en/Tutorial/Sketch">basics on the official website</a>.</p>

<h3>Learning resources</h3>

<p>No where is better equipped at covering everything there is to know about Arduino then the <a href="http://arduino.cc/en/Reference/HomePage">official documentation</a>. Definitely check it out if you want to know how something works, you'll more than likely find the answer there. The <a href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl">official forum</a> is also a perfect place to get help, particularly if you aren't entirely sure what's happening.</p>

<h2>Where to from here?</h2>

<p>By now you should have a better idea about what Arduino is and the kind of things you can do with it. If you're interested by what you've read then I strongly advise going out and buying one of the beginners kits and having a play around. I'll be writing some detailed tutorials on how to achieve particular tasks with the Arduino [manipulating LEDs and sensors, talking to Twitter, etc.] so you can always wait until then to make your mind up.</p>

<p>The most important thing is not being afraid of getting things wrong. Electronics has an air of difficulty associated with it and Arduino is here to change that. Components are cheap and easy to come by so get things wrong and learn from your mistakes. Most of all, have fun.</p>]]></content:encoded>
      <dc:subject></dc:subject>
      <dc:date>2009-12-22T11:00:52+00:00</dc:date>
    </item>

    <item>
      <title>Tracking Multiple Augmented Reality Markers [Video]</title>
      <link>http://rawkes.com/blog/2009/12/18/tracking-multiple-augmented-reality-markers</link>
      <guid>http://rawkes.com/blog/2009/12/18/tracking-multiple-augmented-reality-markers</guid>
      <content:encoded><![CDATA[<p>Work is underway on an augmented reality game involving the use of multiple, trackable, markers.</p>

<figure>
    <object width="620" height="466"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8214397&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8214397&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="620" height="466"></embed></object>
</figure>

<p>This video shows some early development of the code that allows for more than one marker to be tracked on the screen at one time. I've already tested it with 4 markers at a time and I'm confident that it can handle many more than that without a sweat.</p>

<p>Current issues include: tracking being interrupted by glare on the printed symbol, 3d models don't interact with each other.</p>

<p>It goes without saying that there'll be a guide slash tutorial to go along with this in the near future. I'll also be releasing all the code as open source when the game is complete.</p>]]></content:encoded>
      <dc:subject></dc:subject>
      <dc:date>2009-12-18T15:00:09+00:00</dc:date>
    </item>

    
    </channel>
</rss>