<?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>CoderHump.com &#187; Code</title>
	<atom:link href="http://coderhump.com/archives/category/code/feed" rel="self" type="application/rss+xml" />
	<link>http://coderhump.com</link>
	<description>Game Development Technology, in Flash and Elsewhere</description>
	<lastBuildDate>Tue, 06 Jul 2010 17:18:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PushButton Labs Profiler</title>
		<link>http://coderhump.com/archives/606</link>
		<comments>http://coderhump.com/archives/606#comments</comments>
		<pubDate>Tue, 01 Jun 2010 21:42:05 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false">http://coderhump.com/?p=606</guid>
		<description><![CDATA[Do you want your Flash content to perform well?
Have you struggled with the tools built into Flash Builder?
Well, if all you want is a basic functioning profiler, let me introduce the PBLabs Profiler! It shows you where your time is going:

It&#8217;s available under the GPL with source and binaries on GitHub. You can also post [...]]]></description>
			<content:encoded><![CDATA[<p>Do you want your Flash content to perform well?</p>
<p>Have you struggled with the tools built into Flash Builder?</p>
<p>Well, if all you want is a basic functioning profiler, let me introduce the <a href="http://github.com/bengarney/PBLabsProfiler">PBLabs Profiler</a>! It shows you where your time is going:</p>
<p><img src="http://coderhump.com/wp-content/uploads/2010/06/Picture-3.png" alt="" title="PBLabsProfiler Screenshot" width="502" height="382" class="aligncenter size-full wp-image-607" /></p>
<p>It&#8217;s available under the GPL with source and binaries on <a href="http://github.com/bengarney/PBLabsProfiler">GitHub</a>. You can also post on the <a href="http://pushbuttonengine.com/forum/viewforum.php?f=16">PBLabs Profiler forums.</a> There is more information on the profiler in the forums and on the github site.</p>
]]></content:encoded>
			<wfw:commentRss>http://coderhump.com/archives/606/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I Wrote A Book: Video Game Optimization</title>
		<link>http://coderhump.com/archives/585</link>
		<comments>http://coderhump.com/archives/585#comments</comments>
		<pubDate>Mon, 05 Apr 2010 06:16:18 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Cool Stuff]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[Publication]]></category>

		<guid isPermaLink="false">http://coderhump.com/?p=585</guid>
		<description><![CDATA[
More precisely, Eric Preisz and I wrote a  book!
The book is called Video Game Optimization, and it covers everything you need to know to get maximum performance from any software project &#8211; but especially games. If you&#8217;re struggling with getting a great framerate out of your game, I highly recommend checking it out.  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/Video-Game-Optimization-Eric-Preisz/dp/1598634356"><img src="http://coderhump.com/wp-content/uploads/2010/04/photo-225x300.jpg" alt="" title="Ben Garney With Video Game Optimization" width="225" height="300" class="alignleft size-medium wp-image-591" /></a></p>
<p>More precisely, <a href="http://www.torquepowered.com/account/profile/59817">Eric Preisz</a> and I wrote a  <a href="http://www.amazon.com/Video-Game-Optimization-Eric-Preisz/dp/1598634356">book</a>!</p>
<p>The book is called <a href="http://www.amazon.com/Video-Game-Optimization-Eric-Preisz/dp/1598634356">Video Game Optimization</a>, and it covers everything you need to know to get maximum performance from any software project &#8211; but especially games. If you&#8217;re struggling with getting a great framerate out of your game, I highly recommend checking it out. <img src='http://coderhump.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  </p>
<p>Video Game Optimization goes all the way from high-level concepts like planning for performance in your project&#8217;s timeline, to determining which broad area of your system is a bottleneck, down to specific tips and tricks for optimizing for space, time, and interactivity. Based on the course that Eric Preisz taught at Full Sail University on optimization, it isn&#8217;t the only book you&#8217;d ever want to read on the subject, but we think it is a great introduction!</p>
<p>The journey from that initial conversation where our mutual friend <a href="http://www.linkedin.com/in/jdmoore">Jay Moore</a> introduced us and suggested I would be a good co-author, to the day when we finished and shipped the book was a long but rewarding trek. Eric moved across the country from Florida to Nevada, as he moved from teaching at Full Sail University to running the Tech and Tools group at InstantAction. He also became a father with the arrival of his son, Grant. I left after 5 years at GarageGames and helped build a new company, <a href="http://www.pushbuttonlabs.com/">PushButton Labs</a>.</p>
<p>A lot has changed while we wrote it, but it still felt really good to arrive at GDC, visit the book store outside the exhibition hall, and finding a big stack of Video Game Optimization sitting front and center. <img src='http://coderhump.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://coderhump.com/archives/585/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>3D in Flash 10 &amp; Git</title>
		<link>http://coderhump.com/archives/536</link>
		<comments>http://coderhump.com/archives/536#comments</comments>
		<pubDate>Mon, 14 Dec 2009 07:12:05 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[How To]]></category>

		<guid isPermaLink="false">http://coderhump.com/?p=536</guid>
		<description><![CDATA[
I spent a little time with Flash 10&#8217;s 3d features recently. Since Flash 10.1 is imminent and FP10 has been at 90%+ penetration for a while now, it&#8217;s probably safe to start looking at using FP10 stuff in my projects.  
I also used this as an opportunity to try out git. It was easy [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://coderhump.com/wp-content/uploads/2009/12/picture-1.png" alt="picture-1" title="picture-1" width="231" height="196" class="alignright size-full wp-image-537" /></p>
<p><b>I spent a little time with Flash 10&#8217;s 3d features recently.</b> Since Flash 10.1 is imminent and FP10 has been at 90%+ penetration for a while now, it&#8217;s probably safe to start looking at using FP10 stuff in my projects. <img src='http://coderhump.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I also used this as <b>an opportunity to try out git</b>. It was easy to get git installed on OSX (I used the command line version, installed from <a href="http://code.google.com/p/git-osx-installer/">git-osx-installer</a>) and put my code up on <a href="http://www.github.com/">Github</a>. You can browse my test code at <a href="http://github.com/bengarney/garney-experiments/tree/master/exploringFlash3D/">http://github.com/bengarney/garney-experiments/tree/master/exploringFlash3D/</a>.</p>
<p><b>My main concern was the transformation pipeline</b> &#8211; I think there might be some benefits to using 3d positions for the rendering pipeline in PBE. So I wanted to do a brief survey of the built-in 3d capabilities, then look more closely at the transformation routines.</p>
<p>My first test was making a DisplayObject rotate in 3d (<a href="http://github.com/bengarney/garney-experiments/blob/27c17dcd6a6daf828b631f93620b28f83e325038/exploringFlash3D/src/exploringFlash3D.as">minimal source code</a>). It runs well, and if you turn on redraw region display, you can see that it&#8217;s properly calculating the parts of the screen that need to be modified.</p>
<p>This was easy to write, but <b>it revealed the primary flaws with the built-in Flash 3d capabilities</b>. First, look closely &#8211; the edges of the shape were sharp, but the interior detail is aliased. This is because whenever the 3D rendering path is engaged, it turns on cacheAsBitmap. This is fine for simple scenarios (say, taking a single element in a UI and giving it a nice transition) but not for more complex situations.</p>
<p>Which brings us to the second and bigger flaw. I added a thousand simple particle sprites at different 3d positions (<a href="http://github.com/bengarney/garney-experiments/blob/4b2ed8fa9dcc2e9fca4eebc2783fb3b47fa3ce40/exploringFlash3D/src/exploringFlash3D.as">source code</a>). This runs extremely slowly because of <a href="http://www.bit-101.com/blog/?p=2391">an issue described by Keith Peters involving nested 3d transforms<a>. <b>Nested 3d objects cause excessive bitmap caching, dramatically reducing performance.</b> You might end up with bitmap-caching in action on every 3d object and every DisplayObject containing 3d objects.</p>
<p>In addition, because it&#8217;s cached, moving objects further/closer from the camera results in an upsampled/downsampled image. So you tend to get mediocre visual results if your objects move much.</p>
<p>My next step was to stop using the 3d capabilities of DisplayObjects, and just position them in x/y based on their 3D position (<a href="http://github.com/bengarney/garney-experiments/tree/249c73b1387d6e530caadafe1402ad679a79c5ac/exploringFlash3D/src">source code, notice it is two files now</a>). This gave a massive performance gain. At low quality, 1000 particles runs at 1440×700 at acceptable FPS. Most of the overhead is in the Flash renderer, not the code to update DisplayObject positions, but it still takes a while to do all the transformation, and it causes a lot of pressure on the garbage collector from all the 1000 temporary Vector3D instances that are created every frame. (600kb/second or so &#8211; not insignificant.)</p>
<p>Next I figured it would be helpful to make my camera move around (<a href="http://github.com/bengarney/garney-experiments/blob/1abbe2d5e874c5b7097cc55e610b5656e172ca96/exploringFlash3D/src/exploringFlash3D.as">sample code</a>). </p>
<p>This required that I understand the coordinate space all this operated in. What are the coordinate spaces? <a href="http://help.adobe.com/en_US/FlashPlatform/beta/reference/actionscript/3/flash/geom/PerspectiveProjection.html#fieldOfView">According to the official docs</a>, screen XY maps to world XY. So forward is Z+, up is Y-, right is X+. Once I figured that out, I had to prepare a worldMatrix with the transform of the camera, then append the projectionMatrix. The PerspectiveProjection class always seems to assume screen coordinate (0,0) is the center of the projection so you will have to manually offset. Maybe I was not using the projection right, since the docs imply otherwise.</p>
<p>There were two other details to sort out. First, I had to reject objects behind the camera, and second, I had to scale objects correctly so they appeared to have perspective. The solution revolved around the same information &#8211; the pre-projection Z. By hiding all objects with <i>Z &lt; 0</i> and scaling by <i>focalLength / preZ</i>, I was able to get it to behave properly.</p>
<p>Next up is Matrix3D.transformVector… which is slow. <b>Transforming 1000 vectors eats 3ms in release build!</b> This is really slow in absolute terms (<a href="http://www.unitzeroone.com/blog/2009/03/18/flash-10-massive-amounts-of-3d-particles-with-alchemy-source-included/">Ralph Hauwert has a good example of the same functionality running much much faster</a>). I didn’t really want to introduce Alchemy for this project. But we can use AS3 code that avoids the allocations, saving us GC overhead and getting us an incremental improvement in performance.</p>
<p>Andre Michelle has some interesting thoughts on <b>the problem of temporary objects related to transformations</b> (see http://blog.andre-michelle.com/2008/too-late-very-simple-but-striking-feature-request-for-flash10-3d/). I did notice that Utils3D.projectVectors had some options for avoiding allocations, but it did not seem to run significantly faster (even in release build). (<a href="http://github.com/bengarney/garney-experiments/blob/7d98b9d905015002f9c4fcde0c02138ab2817c2c/exploringFlash3D/src/exploringFlash3D.as">sample code for using projectVectors</a>)</p>
<p>In the end, <b>I settled on my own implementation of transformVectors</b>, as it seemed to give the best balance between performance and ease of us. There&#8217;s a <a href="http://github.com/bengarney/garney-experiments/blob/342444710c9563df406b52d4936495d919e31538/exploringFlash3D/src/exploringFlash3D.as">final version of the sample app where you can toggle between transformVector and the AS3 version by commenting out line 105/106</a> up on github, so you can test it for yourself. The transform function took some effort to get right, so here it is to save you the pain of implementing it yourself. It transform i by m and stores it in o.</p>
<pre>        final public function transformVec(m:Matrix3D, i:Vector3D, o:Vector3D):void
        {
            const x:Number = i.x, y:Number = i.y, z:Number = i.z;
            const d:Vector.<Number> = m.rawData;

            o.x = x * d[0] + y * d[4] + z * d[8] + d[12];
            o.y = x * d[1] + y * d[5] + z * d[9] + d[13];
            o.z = x * d[2] + y * d[6] + z * d[10] + d[14];
            o.w = x * d[3] + y * d[7] + z * d[11] + d[15];
        }</pre>
<p>Time for some conclusions. I think that the 3D capabilities built into DisplayObject are OK, but very focused on light-weight graphic design use. <b>Building a significant 3D application requires you write your own rendering code built on Flash&#8217;s 2D capabilities (either DisplayObjects or drawTriangles and friends).</b> The 3d math classes are ok, but immature. Some things are very handy (like the prepend/append versions of all the methods on Matrix3D), but the tendency for Flash APIs to implicitly allocate temporary objects limits the usefulness of some the most central API calls. In addition, important assumptions like the order of the values in Matrix3D.rawData were not documented, leading to frustrating trial and error. <b>I am excited to see Flash&#8217;s 3d capabilities mature.</b> </p>
]]></content:encoded>
			<wfw:commentRss>http://coderhump.com/archives/536/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Adobe, Please Buy HaXe.</title>
		<link>http://coderhump.com/archives/438</link>
		<comments>http://coderhump.com/archives/438#comments</comments>
		<pubDate>Fri, 22 May 2009 21:02:30 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://coderhump.com/?p=438</guid>
		<description><![CDATA[ If you&#8217;re in the Flash space, you&#8217;ve probably seen a lot of coverage of HaXe lately. HaXe targets Flash 9 and 10, as well as JavaScript, PHP, NekoVM, and most recently C++. You can write code once and easily retarget it to different platforms, which is very exciting. This has been used to good [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://coderhump.com/wp-content/uploads/2009/05/haxe_and_neko-150x150.jpg" alt="haxe_and_neko" title="haxe_and_neko" width="150" height="150" class="alignright size-thumbnail wp-image-442" /> If you&#8217;re in the Flash space, you&#8217;ve probably seen a lot of coverage of <a href="http://haxe.org/">HaXe</a> lately. HaXe targets Flash 9 and 10, as well as JavaScript, PHP, NekoVM, and <b>most recently C++</b>. You can write code once and easily retarget it to different platforms, which is very exciting. This has been used to good effect by Hugh Sanderson, who is developing an <a href="http://gamehaxe.com/2009/05/22/haxe-on-iphone-simulator/">iPhone</a> path.</p>
<p>HaXe is cool not only for platform compatibility with things like the iPhone (and who knows &#8211; maybe other platforms like Android or Windows Mobile), but also for its <b>language features</b>. They <a href="http://www.ncannasse.fr/blog/virtual_memory_api">deployed support for the new Flash 10 high-performance memory intrinsics</a> before the official Adobe compiler. HaXe has <a href="http://haxe.org/ref/type_params">generics/templates</a>, decent <a href="http://haxe.org/ref/conditionals">conditional compilation</a>, <a href="http://haxe.org/ref/inline">inlining</a>, <a href="http://haxe.org/ref/type_advanced>advanced typing</a> a lot more. The biggest claim to fame HaXe has is <a href="http://lab.polygonal.de/2009/03/12/hx3ds/">a big performance margin over AS3</a>, as well <a href="http://lab.polygonal.de/2009/03/14/a-little-alchemy-in-hx3ds/">as better memory management options</a>.</p>
<p>And <b>performance is a big deal</b> when you&#8217;re an interpreted language trying to run on <a href="http://en.wikipedia.org/wiki/Netbook">Netbooks</a> and <a href="http://news.bbc.co.uk/1/hi/technology/8008070.stm">televisions</a>.</p>
<p>Since my day (and sometimes nights, too) job is working on a <a href="http://www.pushbuttonengine.com/">Flash game framework</a>, HaXe looms large on my radar. <a href="http://haxe.org/doc/advanced/swc">AS3 and HaXe can already interoperate</a> so if you want to use a HaXe physics library from your ActionScript 3 code, there&#8217;s no problem. But should we switch the core engine over? Having a seamless way to target iPhone would be big. Having an easy way to run your server code without requiring an integration with Tamarin would also be nice.</p>
<p><a href="http://www.unitzeroone.com/blog/2009/05/22/another-scream-on-flash-alchemy-memory-and-compilers/">Ralph Hauwert over at unitzeroone summarizes the HaXe situation</a> very well:</p>
<blockquote><p><i>The language is great and has many features ActionScript lacks. It baffles me how one man army nicolas can single handedly write a language and a multi target compiler, and in many respects stay on top of the ActionScript compiler.</p>
<p>My first problem with Haxe is just that. The one man army. Should nicolas decide he doesn&#8217;t feel like it anymore, the platform is dead. Sure, there&#8217;s more people working on it, but in it&#8217;s core it seems to be that nicolas is the driving force. My second problem is that although there is a huge pool of ActionScript developers, which can work together within the industry standard called ActionScript. There&#8217;s not even near that many people who&#8217;ve even touched haxe, let alone the number of developers who are able to call themselves &#8220;Haxe Professionals&#8221;.</i></p></blockquote>
<p><b>HaXe is very cool.</b> But it doesn&#8217;t have the ecosystem and infrastructure to justify targeting it exclusively. As a small startup, we only get to target one platform for our technology, and AS3, although it leaves performance on the table, wins in terms of the pool of potential developers and the accessibility of the toolchain. How many people out there are using PHP or Java vs. x86 assembly?</p>
<p>If the basic technology is good enough, <b>ease of use always wins out over performance</b>. So for now we are going to stick with ActionScript 3 for <a href="http://www.pushbuttonengine.com">PushButton Engine</a>. You can write compelling content on it. If you really need HaXe for something, the option is there to link it in.</p>
<p>But I want to put the plea out to Adobe. I love you guys and all you have done in the Flash space. But please update your compiler technology. At least give us the compiler optimization wins like <a href="http://blog.haxe.org/entry/31">inlining and generics</a>. It&#8217;s simply embarassing that one guy&#8217;s work can outperform you on your own VM! </p>
<p>Adobe, you have smart people working for you. You have smart people in your community. You have pretty decent tools. None of us want to jump over to a third-party technology, but if HaXe keeps beating you at your own game, it might be necessary. <b>Buy HaXe if you must</b>, or else match it with your in-house tech, but either way &#8211; I know you can solve this problem. </p>
<p>The web is catching up with you on the player front. You could dominate on the tools front and make the world better for everyone. Please. As a middleware developer, I really don&#8217;t want to have to support anything other than a single mainstream language and platform. <img src='http://coderhump.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://coderhump.com/archives/438/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Technical Notes on O3D</title>
		<link>http://coderhump.com/archives/427</link>
		<comments>http://coderhump.com/archives/427#comments</comments>
		<pubDate>Tue, 21 Apr 2009 22:23:49 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Cool Stuff]]></category>
		<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://coderhump.com/?p=427</guid>
		<description><![CDATA[
Google released O3D, a web plugin for 3d rendering, today. It&#8217;s a pretty sweet piece of work. Definitely check it out if you have any interest in 3d rendering, the web, or JavaScript.
There are a couple of cool pieces to this puzzle, and I wanted to call them out to other people who might be [...]]]></description>
			<content:encoded><![CDATA[<p><center><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/uofWfXOzX-g&#038;rel=0&#038;color1=0xb1b1b1&#038;color2=0xcfcfcf&#038;hl=en&#038;feature=player_embedded&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><embed src="http://www.youtube.com/v/uofWfXOzX-g&#038;rel=0&#038;color1=0xb1b1b1&#038;color2=0xcfcfcf&#038;hl=en&#038;feature=player_embedded&#038;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed></object></center></p>
<p><b>Google released <a href="http://code.google.com/apis/o3d/">O3D, a web plugin for 3d rendering</a>, today.</b> It&#8217;s a pretty sweet piece of work. Definitely check it out if you have any interest in 3d rendering, the web, or JavaScript.</p>
<p>There are a couple of cool pieces to this puzzle, and I wanted to call them out to other people who might be reviewing this technology. The two sentence review: <b>I am blown away. They got this right.</b></p>
<p>(FYI: This post isn&#8217;t meant to be a full walkthrough, just a quick indication of the cool jumping off points in the codebase.)</p>
<p>Stop number one is <b>the graphics API abstraction</b>. This is rooted in <a href="http://o3d.googlecode.com/svn/trunk/googleclient/o3d/core/cross/renderer.h">o3d/core/cross/renderer.h</a>, which provides an abstract interface for performing render operations. This is sensibly designed, oriented for SM2.0 through SM4.0 level hardware. It will also deal with DX11 class hardware, although it won&#8217;t expose all of the niceties DX11 gets you. It wraps GL (<a href="http://o3d.googlecode.com/svn/trunk/googleclient/o3d/core/cross/gl/">o3d/core/cross/gl/</a>) and D3D9 (<a href="http://o3d.googlecode.com/svn/trunk/googleclient/o3d/core/win/d3d9/">o3d/core/win/d3d9</a>). The purpose of all this is to provide a common ground for all the higher level code to issue draw commands from. It is not directly accessible from JavaScript (although some of the related classes like <a href="http://code.google.com/apis/o3d/docs/reference/classo3d_1_1_sampler.html">Sampler</a> and <a href="http://code.google.com/apis/o3d/docs/reference/classo3d_1_1_state.html">State</a> are.)</p>
<p>As an aside, writing a <a href="http://www.radgametools.com/pixomain.htm">Pixomatic</a> or <a href="http://en.wikipedia.org/wiki/Larrabee_(GPU)">Larrabee</a> backend would not be hard. At <a href="http://www.garagegames.com/">GarageGames</a>, we had a rendering API similar to this (unimaginatively called GFX), and it was fantastically useful. Last time I checked, there were DX8, DX9, DX10/11, GL, and Pixomatic backends for it in varying states of usefulness. We even had one guy write a backend that would stream draw commands over a socket, which was pretty cool. In the context of O3D, they have <a href="http://o3d.googlecode.com/svn/trunk/googleclient/o3d/core/cross/command_buffer/">an implementation of Renderer that queues everything into command_buffer</a>, then streams it to a <a href="http://o3d.googlecode.com/svn/trunk/googleclient/o3d/core/win/command_buffer/">command buffer server</a> running in a separate thread, which issues the actual draw commands. It&#8217;s unclear whether this is used in the current version of the plugin based on casual inspection, but it&#8217;s a great example of what good design can get you.</p>
<p>The next piece is <b>the DrawList</b>, which is where most of the heavy lifting for drawing happens. JavaScript, of course, is not really desirable to have in your inner rendering loops, so you queue everything you want to draw (<a href="http://code.google.com/apis/o3d/docs/reference/classo3d_1_1_draw_element.html">DrawElements</a>) into a <a href="http://code.google.com/apis/o3d/docs/reference/classo3d_1_1_draw_list.html">DrawList</a>. This is wrapped by higher levels, of course, but it represents the lowest level API that&#8217;s available to JS code. All the sorting and state management to get stuff on screen happens in this area.</p>
<p>Alongside the DrawList stuff, you find <b>the <a href="http://code.google.com/apis/o3d/docs/shadinglanguage.html">material system</a></b>, which is pretty slick. You write your shaders in their shading language, and it converts to HLSL SM2.0 and Cg (arbvp1/arbfp1). This is enough to do almost anything you might want to (as fantastic as SM3.0+ is it&#8217;s not really necessary for most rendering). There&#8217;s a full SAS system so you can interface programmatically with your shaders.</p>
<p>Above this, you get into <b>the scenegraph</b>. Now, I subscribe to <a href="http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BScene%20Graphs%20-%20just%20say%20no%5D%5D">Tom Foryth&#8217;s views on scenegraphs</a>, which is that they are basically a bad idea, but I think the Google guys were smart and set up their API so intelligent developers can avoid being screwed by the scenegraph. The scenegraph-esque stuff they do have (<a href="http://code.google.com/apis/o3d/docs/rendering.html">they call it a rendergraph</a>) is powerful enough you can do most rendering without going nuts, and lets a lot of the heavy lifting stay in native code, where it will be fast. You end up doing retained mode-ish things, but since JS is slow, and most JS developers come from a DOM background, it works better than you might expect.</p>
<p>There are a lot of <b>cool miscellaneous features</b>, too. They <a href="http://code.google.com/apis/o3d/docs/v8engine.html">embed the fast V8 JS engine</a> right in the plugin so you can have consistently fast JS execution. They support falling back to an <a href="http://code.google.com/apis/o3d/docs/reference/classo3d_1_1_client.html#49f18f81e6184cbeeeb87306f0cf59ca">error texture (via Client.SetErrorTexture)</a> when you fail to bind a sampler.  You can group objects via <a href="http://code.google.com/apis/o3d/docs/reference/classo3d_1_1_pack.html">Pack</a> objects for easier management and <a href="http://code.google.com/apis/o3d/docs/reference/classo3d_1_1_archive_request.html">stream things from archives</a>, too. There are <a href="http://code.google.com/apis/o3d/docs/reference/jsdocs/js_1_0_o3djs.debug_ref.html">debugging aids</a> and libraries for <a href="http://code.google.com/apis/o3d/docs/reference/jsdocs/js_1_0_o3djs.math_ref.html">math</a> and <a href="http://code.google.com/apis/o3d/docs/reference/jsdocs/js_1_0_o3djs.quaternions_ref.html">quaternions</a>.</p>
<p>You should check out the <a href="http://code.google.com/apis/o3d/docs/samplesdirectory.html#demos">samples</a>. There&#8217;s a lot of impressive stuff. There&#8217;s the <a href="http://o3d.googlecode.com/svn/trunk/samples/beachdemo/beachdemo.html">beach demo</a> in the video at the top of this post, but they also do some cool stuff with <a href="http://o3d.googlecode.com/svn/trunk/samples/animated-scene.html">animation</a>, <a href="http://o3d.googlecode.com/svn/trunk/samples/hud-2d-overlay.html">HUDs</a>, <a href="http://o3d.googlecode.com/svn/trunk/samples/canvas-fonts.html">text rendering</a>, <a href="http://o3d.googlecode.com/svn/trunk/samples/picking.html">picking</a>, and <a href="http://o3d.googlecode.com/svn/trunk/samples/stencil_example.html">stenciled teapots</a>. And everything is done in JavaScript right in the web page. Even the shaders are embedded in &lt;script&gt; tags!</p>
<p><b>O3D is a great piece of technology</b>, and I hope it thrives. I&#8217;m excited to see what people build on this (and I&#8217;ve got a few ideas myself <img src='http://coderhump.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://coderhump.com/archives/427/feed</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Tweaking your game with Google Spreadsheets</title>
		<link>http://coderhump.com/archives/385</link>
		<comments>http://coderhump.com/archives/385#comments</comments>
		<pubDate>Sun, 01 Feb 2009 07:42:04 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Cool Stuff]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[PushButton Engine]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[spreadsheets]]></category>
		<category><![CDATA[tweak]]></category>

		<guid isPermaLink="false">http://coderhump.com/?p=385</guid>
		<description><![CDATA[ Our latest game, Grunts: Skirmish, has 200 tweakable parameters. There are 9 player units with three levels of upgrade, and another 9 enemy units. Each unit has between three and ten parameters that can be altered.
We tried a few approaches &#8211; hand-editing a large XML file (but it was too large and spread out) [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://coderhump.com/wp-content/uploads/2009/02/tweaksheet.png" alt="tweaksheet" title="tweaksheet" width="300" height="270" class="alignright size-full wp-image-386" /> Our latest game, <a href="http://makeitbigingames.com/2009/01/woohoo-grunts-skirmish-has-a-logo/">Grunts: Skirmish</a>, has <b>200 tweakable parameters</b>. There are 9 player units with three levels of upgrade, and another 9 enemy units. Each unit has between three and ten parameters that can be altered.</p>
<p>We tried a few approaches &#8211; <b>hand-editing a large XML file</b> (but it was too large and spread out) and an in-game <b>tweaking UI</b> (but it was too much work to get the UI to be friendly to use). The old standby of having <a href="http://makeitbigingames.com/">the designer</a> and <a href="http://subreal.net/">artist</a> <b>file bug reports</b> to have <a href="http://coderhump.com/">the programmer</a> update the game wasn&#8217;t getting us very far, either.</p>
<p>&#8220;Well,&#8221; says I, &#8220;We&#8217;re some sort of Web 2.0 startup, right? And we&#8217;re developing a Flash game aren&#8217;t we? And Flash can talk to websites, can&#8217;t it? And don&#8217;t we use Google Docs for everything?&#8221;</p>
<p>It turns out there is an <a href="http://code.google.com/apis/spreadsheets/docs/2.0/reference.html#CellFeed">XML feed from public Google spreadsheets</a>. And ActionScript 3 supports <a href="http://en.wikipedia.org/wiki/E4X">E4X</a>, so you can directly manipulate XML without any extra work. <b>Now we tweak our game using a shared spreadsheet up on Google Docs.</b></p>
<p>I wrote a parser for their format:</p>
<pre><code>// Extract the entries. It's namespaced, so deal with that.
var xmlns:Namespace = new Namespace("xmlns", "http://www.w3.org/2005/Atom");
tweakXML.addNamespace(xmlns);

// Parse into a dictionary.
var cellDictionary:Dictionary = new Dictionary();
for each(var entryXML:XML in tweakXML.xmlns::entry)
{
   cellDictionary[entryXML.xmlns::title.toString()] = entryXML.xmlns::content.toString();
}</code></pre>
<p>And wrote a quick component that would fetch the spreadsheet feed, parse it, and stuff it into the right places on named objects or template data. Now I have a little entry in our level file that looks like:</p>
<pre><code>&lt;object id="googleTweaker"&gt;
   &lt;component class="com.pblabs.debug.GoogleSpreadsheetTweaker"&gt;
     &lt;SpreadsheetUrl&gt;http://spreadsheets.google.com/feeds/cells/0d8somekey848x/od6/public/basic&lt;/SpreadsheetUrl&gt;
     &lt;Config&gt;
        &lt;!--  Grunt Level 1 tweaks --&gt;
        &lt;_&gt;&lt;Cell&gt;B3&lt;/Cell&gt;&lt;Property&gt;#TheGruntProxy.creator.WarPointCost&lt;/Property&gt;&lt;/_&gt;
        &lt;_&gt;&lt;Cell&gt;C3&lt;/Cell&gt;&lt;Property&gt;!Grunt.health.mMaxHealth&lt;/Property&gt;&lt;/_&gt;
        &lt;_&gt;&lt;Cell&gt;D3&lt;/Cell&gt;&lt;Property&gt;!Grunt.ai.AttackSearchRadius&lt;/Property&gt;&lt;/_&gt;
     &lt;/Config&gt;
  &lt;/component&gt;
&lt;/object&gt;</code></pre>
<p>Each line maps a cell in the spreadsheet to a property on a template or active game object. Some properties have to be set several places, which the system deals with automatically.</p>
<p>The biggest wrinkle was Google&#8217;s crossdomain.xml policy. Basically they do not allow random Flash apps to access their site. So I had to write a small proxy script, which sits on our development server next to the game and fetches the data for it. Figuring out I had to do this took more time than any other step.</p>
<p>The main difference between the snippet and the full code is the version in our repository is 220 lines long. I only have around 150 of the full set of 200 parameters hooked up, but after a hard afternoon&#8217;s work, the process for tweaking the game has become:</p>
<ol>
<li>Open Google Docs.</li>
<li>Edit a clearly labeled value &#8211; like level 1 grunt health.</li>
<li>Restart the game, which is running in another tab in your browser.</li>
</ol>
<p><b>This takes you about a minute between trials.</b> Not too bad. Before this, the process was:</p>
<ol>
<li>Get the game source from SVN.</li>
<li>Find the right XML file &#8211; there are several.</li>
<li>Find the right section in the XML &#8211; altogether we have 200kb of the stuff for Grunts!</li>
<li>Change the value.</li>
<li>Commit the change.</li>
<li>Wait 5-15 minutes for the build system to refresh the live version of the game.</li>
</ol>
<p><b>Ten minutes per tweak is not a good way to develop.</b></p>
<p>I&#8217;ve heard about developers using Excel spreadsheets for tweaking, but can&#8217;t find anything about using Google Docs to do it. <b>But Google Spreadsheet is obviously a better choice</b>. It has built-in revision tracking. You can edit it simultaneously with someone else. You can access live data in XML either publicly (like we did) or privately via their authentication API. It&#8217;s absolutely worth the half-day of your time it will take to add Google Spreadsheet-based tweaking to your game &#8211; even if it&#8217;s a non-Flash game, downloading and parsing XML is pretty easy with the right libraries.</p>
<p>I strongly suspect this feature will find its way into the next beta of the <a href="http://www.pushbuttonengine.com/">PushButton Engine</a>. Which, by the way, you should sign up for if you are interested in developing Flash games. <b>We&#8217;re bringing people in from the signup form starting this week.</b> If you want more information, or just like looking at cool websites, click below to check out the new version of the PBEngine site, which has a bunch of information on the tech. <a href="http://subreal.net/">Tim</a> did an awesome job on the site design.</p>
<p><a href="http://pushbuttonengine.com/"><img src="http://coderhump.com/wp-content/uploads/2009/02/betashot.png" alt="betashot" title="betashot" width="565" height="217" class="aligncenter size-full wp-image-400" /></a></p>
<p><b>Edit:</b> Patrick over on the GG forums asked about the proxy script. It&#8217;s actually ludicrously simple. Not very secure either so I wouldn&#8217;t recommend deploying it on a public server. I got my script from a post on <a href="http://www.adenforshaw.co.uk/?p=4">Aden Forshaw&#8217;s blog</a>. In the real world you would want to have some security token to limit access to your proxy script&#8230; but since this is for tweaking a game that is in development I didn&#8217;t sweat it.</p>
]]></content:encoded>
			<wfw:commentRss>http://coderhump.com/archives/385/feed</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Array Ordering in ActionScript 3</title>
		<link>http://coderhump.com/archives/322</link>
		<comments>http://coderhump.com/archives/322#comments</comments>
		<pubDate>Tue, 06 Jan 2009 04:03:09 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://coderhump.com/?p=322</guid>
		<description><![CDATA[Update: I filed a bug about this issue.
 This post starts out with a finite state machine, but it ends up talking about how iteration is implementing in ActionScript.
There I was &#8211; implementing a finite state machine. Each state had transitions, and the transitions are named and, additionally, processed in order. This is useful because [...]]]></description>
			<content:encoded><![CDATA[<p><i><b>Update:</b> I filed a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=472340">bug</a> about this issue.</i></p>
<p><img src="http://coderhump.com/wp-content/uploads/2009/01/coils.jpg" alt="coils" title="coils" width="240" height="193" class="alignright size-full wp-image-328" /> This post starts out with a finite state machine, but it ends up talking about how iteration is implementing in ActionScript.</p>
<p>There I was &#8211; implementing a finite state machine. Each state had transitions, and the transitions are named and, additionally, processed in order. This is useful because you can order your transitions for consideration from most to least specific. Usually the last transition is unconditional.</p>
<p>Unfortunately, I began encountering issues with users who had the release player installed. Enemies would move erratically and transition between states inappropriately. Adding and removing log statements would sometimes make the problem go away, other times not. I suspected the VM or compiler.</p>
<p>As you may be aware the <i>for</i> and <i>for each</i> keywords in Flash are not guaranteed to iterate over keys or values in a consistent order. And of course, my loop for checking transitions looks like:</p>
<pre><code>
      	// Evaluate transitions in order until one goes.
      	for each(var t:ITransition in Transitions)
      	{
      		if(t.Evaluate(fsm) &#038;&#038; fsm.SetCurrentState(t.GetTargetState()))
      			return;
      	}
</code></pre>
<p>The icing on the cake is the hashtable implementation in Tamarin, which is used internally for storing object properties as well as (partially) for Arrays. Whenever you store a value by key, the key is converted to an atom, and the atom is used as the key for the hash table look up. Atoms are (basically) pointers, so the location in the hash table is based on the memory allocation pattern of your SWF (as well as the allocations of the player binary you are using). (See <a href="http://hg.mozilla.org/tamarin-central/file/2cee46be9ce0/core/avmplusHashtable.cpp#l122">HashTable::find</a> for the implementation behind this.)</p>
<p>In other words, the order of iteration will be random, but consistent for a given combination of player binary and SWF (and execution pattern). In my case, the iteration order was what you&#8217;d expect (order of addition to the Array) for debug player, and backwards for release player. A case of good luck turning bad, since it led me to believe that everything was working correctly in the debug player.</p>
<p>How does this relate to the log statements I mentioned earlier? Because iteration order is tied to memory allocations, it looked like a VM or compiler bug, since adding or removing code would change memory allocation patterns.</p>
<p>From this experience, I have two pieces of knowledge to share.</p>
<p>First, if you need to have both non-integer keys and values, but want to iterate in a specific order, you can&#8217;t use any of the built-in ActionScript classes. Instead, use a class like senocular.com&#8217;s <a href="http://www.senocular.com/flash/actionscript.php?file=ActionScript_3.0/AssociativeArray.as">AssociativeArray</a>, which subclasses <a href="http://livedocs.adobe.com/flex/2/langref/flash/utils/Proxy.html">flash.utils.Proxy</a> to implement custom iteration logic.</p>
<p>Second, some parts of ActionScript <b>do</b> iterate in a consistent order:</p>
<ul>
<li><b>&#8220;Dense&#8221; Arrays</b> will iterate in order from first to last element. You can see the implementation for this in <a href="http://hg.mozilla.org/tamarin-central/file/2cee46be9ce0/core/ArrayObject.cpp">ArrayObject</a>. &#8220;Dense&#8221; mode is heuristic but activated by having numeric indexes, especially starting at zero.</li>
<li><b>XML nodes.</b> Children have a definite order based on the document and are iterated in this order.</li>
</ul>
<p><br/></p>
<p>The docs don&#8217;t describe this, to the best of my knowledge, which is why I post here. The best I can find is this from the <a href="http://livedocs.adobe.com/flex/201/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&#038;file=03_Language_and_Syntax_160_16.html">online docs</a>:</p>
<blockquote><p><i>For example, you can use a for..in loop to iterate through the properties of a generic object (object properties are not kept in any particular order, so properties may appear in a seemingly random order)</i></p></blockquote>
<p>Is there any more information out there? I&#8217;d like to think I&#8217;m overlooking something!</p>
<p><i>Thanks to Steven Johnson of Adobe &#8211; his feedback was essential in the process of sorting this out. Creative Commons picture by <a href="http://flickr.com/photos/davebluedevil/312297641/">davebluedevil</a>.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://coderhump.com/archives/322/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ActionScript 3 Reflection: list fields on an object with ClassFieldCache</title>
		<link>http://coderhump.com/archives/218</link>
		<comments>http://coderhump.com/archives/218#comments</comments>
		<pubDate>Thu, 12 Jun 2008 03:40:32 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://coderhump.com/?p=218</guid>
		<description><![CDATA[Say you’re working on some sort of reflection/deserialization system in Flex, Flash, or another ActionScript 3 technology. It would be nice to know the type of all the fields on an object or class, including accessors, so that you can automagically infer the right way to parse your serialization data. You can use describeType to [...]]]></description>
			<content:encoded><![CDATA[<p>Say you’re working on some sort of reflection/deserialization system in Flex, Flash, or another ActionScript 3 technology. It would be nice to know the type of all the fields on an object or class, including accessors, so that you can automagically infer the right way to parse your serialization data. You can use describeType to do this but it has some overhead &#8211; dumping a full XML description of a complex type can’t be something you’d want to do frequently, and then you have to parse it again.</p>
<p>I present the ClassFieldCache. It contains one static method, getFieldsOfClass, which will return a dictionary of types indexed by field name. It returns every kind of property you can set &#8211; both fields and accessors. (And it ignores constants and readonly accessors.)</p>
<p>Usage is like this:</p>
<pre>
	var dict:Dictionary = ClassFieldCache.getFieldsOfClass(myObject);
	trace("Field boo is of type " + dict["boo"]);
</pre>
<p>Which outputs “Field boo is of type flash.geom::Point” &#8211; or whatever that field happens to be.</p>
<p>And the class itself is as follows:</p>
<pre>
	import flash.utils.*;

	/**
	 * Utility class to get list of fields on an object or class.
	 */
	public class ClassFieldCache
	{
		/// Indexed by Class, this contains dictionaries mapping name to type (string).
		private static var smFieldInfoCache:Dictionary = new Dictionary(true);

		/**
		 * Return a dictionary describing every settable field on this object or class.
		 *
		 * Fields are indexed by name, and the type is contained as a string.
		 */
		public static function getFieldsOfClass(c:*):Dictionary
		{
			if(!(c is Class))
			{
				// Convert to its class.
				c = getDefinitionByName(getQualifiedClassName(c));
			}

			// Is it cached? If so, return that.
			if(smFieldInfoCache.hasOwnProperty(c))
				return smFieldInfoCache[c];

			// Otherwise describe the type...
			var typeXml:XML = describeType(c);

			// Set up the dictionary
			var typeDict:Dictionary = new Dictionary();

			// Walk all the variables...
			for each (var variable:XML in typeXml.factory.variable)
				typeDict[variable.@name.toString()] = variable.@type.toString();

			// And all the accessors...
			for each (var accessor:XML in typeXml.factory.accessor)
			{
				// Ignore ones we can't write to.
				if(accessor.@access == "readonly")
					continue;

				typeDict[accessor.@name.toString()] = accessor.@type.toString();
			}

			// Don't forget to stuff it in the cache. <img src="http://coderhump.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley"/>
			smFieldInfoCache[c] = typeDict;
			return typeDict;
		}
	}
</pre>
<p>Hope this is useful for you. You’re free to use it however you like. Attribution would be appreciated.</p>
]]></content:encoded>
			<wfw:commentRss>http://coderhump.com/archives/218/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Forest Pack &#8211; Finally out the door</title>
		<link>http://coderhump.com/archives/224</link>
		<comments>http://coderhump.com/archives/224#comments</comments>
		<pubDate>Sat, 27 Oct 2007 03:44:03 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Publication]]></category>

		<guid isPermaLink="false">http://coderhump.com/?p=224</guid>
		<description><![CDATA[
It took a few years, but I finally released the fixed function GL forest renderer I was working on for Torque. You can find out all about it at my .plan on GarageGames. Various businessy things got in the way of releasing it (and perhaps a bit of apathy on my own part  … [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/bengarney/75023510/" title="Photo Sharing" target="_blank"><img src="http://farm1.static.flickr.com/9/75023510_01f1016385.jpg" width="500" alt="Trees With Shadows"/></a></p>
<p>It took a few years, but I finally released the fixed function GL forest renderer I was working on for Torque. You can find out all about it at <a href="http://www.garagegames.com/blogs/8863/13768" target="_blank">my .plan on GarageGames</a>. Various businessy things got in the way of releasing it (and perhaps a bit of apathy on my own part <img src="http://coderhump.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley"/> … but it’s nice to have it out! Done with? We’ll see. There’s always a lot of question/answer and trouble-shooting to go with these things.</p>
<p>On a personal level, I like to think this heralds a new chapter of my life, where things Just Get Done a lot more often. We’ll see how that pans out.</p>
]]></content:encoded>
			<wfw:commentRss>http://coderhump.com/archives/224/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SpaceNavigator Support for Sauerbraten</title>
		<link>http://coderhump.com/archives/226</link>
		<comments>http://coderhump.com/archives/226#comments</comments>
		<pubDate>Sat, 13 Oct 2007 03:45:10 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://coderhump.com/?p=226</guid>
		<description><![CDATA[ I recently got a 3dconnexion SpaceNavigator after trying a friend’s. Really neat device. 6 degrees of freedom in a slick little package, and only $50. And it’s actually fun to use &#8211; not frustrating and cheap-feeling like many other “weird” input devices I’ve tried. Its big brother is the same knob with some extra [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://coderhump.com/wp-content/uploads/2007/10/spacenavigator1.thumbnail.jpg" alt="SpaceNavigator" align="left" hspace="7" vspace="7/"/> I recently got a <a href="http://www.3dconnexion.com/3dmouse/spacenavigator.php" target="_blank">3dconnexion SpaceNavigator</a> after trying a friend’s. Really neat device. 6 degrees of freedom in a slick little package, and only $50. And it’s actually fun to use &#8211; not frustrating and cheap-feeling like many other “weird” input devices I’ve tried. Its big brother is the same knob with some extra buttons &#8211; for only $400. Yikes. Yet I’m beginning to see why you might want to upgrade…</p>
<p>Anyway, I did a lame integration with <a href="http://www.sauerbraten.org/" target="_blank">Sauerbraten</a>, an open-source 3d engine, under Win32 against the 3dconnexion SDK. The integration is pretty simple &#8211; even crude. This is another code post, skip if you’re not a techy! <img src="http://coderhump.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley"/></p>
<p><a target="_blank"><br />
</a></p>
<p>First, grab <a href="spaceNav.cpp" target="_blank">this file (spaceNav.cpp)</a> and add it to the Sauerbraten project. Then add a COM reference to the TDxInput that ships with the 3d connexion SDK (which you can <a href="http://www.3dconnexion.com/support/sdk.php" target="_blank">download here</a>). Finally, go to engine/main.cpp and add:</p>
<blockquote><pre>extern void spaceNav_start();
extern void spaceNav_poll();

void updateCameraFromSpaceNav(float tX, float tY, float tZ, float rX, float rY, float rZ, float rAngle)
{
   // Construct a matrix from our cur yaw/pitch/roll
   matrix m(vec(1,0,0), vec(0,1,0), vec(0,0,1));

   m.rotate(-camera1-&gt;yaw * RAD,   vec(0,0,1));

   m.X.mul(tX / 10.f);
   m.Y.mul(-tY / 10.f);
   m.Z.mul(tZ / 10.f);

   camera1-&gt;vel.add(m.X);
   camera1-&gt;vel.add(m.Y);
   camera1-&gt;vel.add(m.Z);
}</pre>
</blockquote>
<p>Right before the main function (around line 434).</p>
<p>Right after the line that reads:</p>
<blockquote><pre>    SDL_ShowCursor(0);</pre>
</blockquote>
<p>Add:</p>
<blockquote><pre>    spaceNav_start();</pre>
</blockquote>
<p>And around line 630, inside the for(;;), add:</p>
<blockquote><pre>               spaceNav_poll();</pre>
</blockquote>
<p>You can bind to the SpaceNavigator buttons by setting up keymaps like…</p>
<blockquote><pre>keymap -131 SPACENAV_LEFT</pre>
</blockquote>
<p>…and similar to a cfg file that gets executed when Sauerbraten starts up &#8211; I used keymap.cfg. Then you can bind to SPACENAV_LEFT and execute whatever commands you like. The binding uses button ids -100 through -132. 31 and 32 are the two buttons on the SpaceNavigator. On other 3dconnexion products there are more buttons and thus you can make use of the other binds.</p>
<p>And that’s it. spaceNav_start() loads up the SpaceNavigator COM object, Connect()s to the driver, and sets some global. spaceNav_poll() queries state and calls updateCameraFromSpaceNav() with the current state. It also dispatches to keypress() when a button is hit so the console can deal with binds.</p>
<p><b>Known issues:</b></p>
<ul>
<li>Not networked properly. I’m just stuffing into the camera1 entity’s velocity field. It’s good enough to edit with, which is what I want.
</li>
<li>Not based on frame time, so will give different behavior based on framerate.
</li>
<li>No rotation. Since you have to aim with the mouse anyway this didn’t seem like a big need, but if someone made clicking independent of heading it could be a really useful feature… It does take the yaw into account when translating so you can fly around pretty well.
</li>
<li>Not configurable. You can tweak the code in updateCameraFromSpaceNav to change how/how fast you move but it would be better to have that all be console-controllable.
</li>
</ul>
<p><b>Conclusion</b></p>
<p>I hope this is useful to someone! Feel free to do what you like with this code. Sauerbraten is under zlib, and 3d connexion SDK probably has some restrictions, too.</p>
]]></content:encoded>
			<wfw:commentRss>http://coderhump.com/archives/226/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
