<?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>zero point nine &#187; sourcecode</title>
	<atom:link href="http://www.zeropointnine.com/blog/category/sourcecode/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zeropointnine.com/blog</link>
	<description>lee felarca - personal work and findings</description>
	<lastBuildDate>Fri, 04 Nov 2011 13:19:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>FPO Image Generator</title>
		<link>http://www.zeropointnine.com/blog/fpo-image-generator/</link>
		<comments>http://www.zeropointnine.com/blog/fpo-image-generator/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 15:07:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[sourcecode]]></category>

		<guid isPermaLink="false">http://www.zeropointnine.com/blog/?p=1018</guid>
		<description><![CDATA[Is it not the norm for the agency developer of whatever flavor to be asked make more progress than what&#8217;s reasonable based on the current status of a given project at any given point in time? Thus, we continuously look for ways to make more progress with less information, even while increasing the risk of [...]]]></description>
			<content:encoded><![CDATA[<div class="paragraph1">
<div class="imageright"><a href="/blog/assets/FpoImageGenerator_screenshot.jpg" target="_blank"><img border="0" src="/blog/assets/FpoImageGenerator_thumb.jpg" alt="Thumbnail" /></a></div>
<p>Is it not the norm for the agency developer of whatever flavor to be asked make more progress than what&#8217;s reasonable based on the current status of a given project at any given point in time?</p>
<p>Thus, we continuously look for ways to make more progress with less information, even while increasing the risk of wasted work and unseemly displays of developer angst. At the very least, such experiences make a person receptive to finding a few tricks that might shave off a few extra minutes in one&#8217;s pursuit to meet the latest unreasonable deadline. </p>
<p>That having been said, the potential utility of this little tool should require no further explanation.</p>
<p>It has its origins in this capricious <a href="http://twitter.com/#!/zeropointnine/status/27805279504568320" target="_blank">tweet</a> from some time last winter.</p>
<p>- <a href="/blog/assets/FpoImageGenerator_20111103.air"><strong>Download</strong></a> (uses Adobe AIR)</p>
<p>- <a href="/blog/assets_code/FpoImageGenerator_source_09.zip"><strong>Source</strong></a> (Flex project)
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.zeropointnine.com/blog/fpo-image-generator/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Updated FLV Encoder, 3.5x faster with Alchemy</title>
		<link>http://www.zeropointnine.com/blog/updated-flv-encoder-alchem/</link>
		<comments>http://www.zeropointnine.com/blog/updated-flv-encoder-alchem/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 14:32:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[sourcecode]]></category>

		<guid isPermaLink="false">http://www.zeropointnine.com/blog/?p=898</guid>
		<description><![CDATA[Demo: Record and encode FLV&#8217;s from webcam in realtime, using AlchemyOr, download AIR desktop version This is an update to FLV Encoder which adds an optional Alchemy routine that&#8217;s about 3.5x faster, as well as FileStream support for writing directly to a local file using AIR. The library has been architected in such a way [...]]]></description>
			<content:encoded><![CDATA[<div class="vimeoBox" style="padding-left:20px; padding-bottom:10px; width:200px;"><img src="/blog/assets/WebcamRealTimeFlvEncoder_thumb.jpg" onclick="javascript:showBox('WebcamRealTimeFlvEncoder',340,440,'e5e5e5',this);" alt="Thumbnail - Click me" style="cursor: pointer" />
<div style="padding-top:12px;"><em>Demo: Record and encode FLV&#8217;s from webcam in realtime, using Alchemy<br/><br/>Or, <a href="/blog/assets/WebcamRealtimeFlvEncoder.air">download AIR desktop version</a></em></div>
</div>
<p>This is an update to FLV Encoder which adds an optional Alchemy routine that&#8217;s about 3.5x faster, as well as FileStream support for writing directly to a local file using AIR. The library has been architected in such a way that you can use the package while targeting either the browser (no FileStream support) or AIR, and either Flash 9 (no Alchemy support) or Flash 10 &#8211; without getting class dependency compiler errors. </p>
<p>I&#8217;ve put the package on <a href="https://github.com/zeropointnine/leelib" target="_blank">Github</a>, along with a couple examples (including the one from the <a href="http://www.zeropointnine.com/blog/flv-encoder-with-audio/">last post</a>). The API has changed a little so be sure to also see the example code below. A method <code>updateDurationMetadata()</code> has been added so the video duration does not have to be declared before the video has been created. Also, a bug where the top-most line of pixels was not being written has been fixed.</p>
<p><strong>Realtime encoding demo:</strong></p>
<p>Because of the increased speed of the Alchemy version, it is now viable to encode FLV&#8217;s in realtime as the audio and video is being captured, at least within certain limits. Click on the thumbnail above for an online demo that encodes webcam video and audio to a file at 320&#215;240 in real time. If your system is fast enough, you can keep the framerate set to 15FPS with minimal hiccups. The browser-based version must store the entire FLV in memory before saving to disk, but the <a href="/blog/assets/WebcamRealtimeFlvEncoder.air">equivalent AIR version</a> can save its contents directly to a file so that the only limiting factor is disk space. I&#8217;m using a dynamic timing and queuing system to keep video and audio in sync which could be the topic of another post.</p>
<p><strong>Updated usage examples:</strong></p>
<p><span id="more-898"></span></p>
<p>[A] To encode an FLV to a ByteArray, start by instantiating <code>ByteArrayFlvEncoder</code>. The rest is similar to the last version, but you can now call <code>updateDurationMetadata()</code> when you&#8217;re done to update the duration property in the metadata. Finally, call <code>kill()</code> to prepare the object for garbage collection:</p>
<p>[as3]<br />
var baFlvEncoder:ByteArrayFlvEncoder = new ByteArrayFlvEncoder(myFrameRate);</p>
<p>baFlvEncoder.setVideoProperties(myWidth, myHeight, VideoPayloadMakerAlchemy);<br />
// (Omit the 3rd argument to NOT use Alchemy if you&#8217;re targeting Flash 9)<br />
baFlvEncoder.setAudioProperties(BaseFlvEncoder.SAMPLERATE_44KHZ, true, false, true);</p>
<p>baFlvEncoder.start();</p>
<p>baFlvEncoder.addFrame(myBitmapData, myAudioByteArray);<br />
baFlvEncoder.addFrame(myBitmapData, myAudioByteArray); // etc.</p>
<p>baFlvEncoder.updateDurationMetadata();</p>
<p>saveOutMyFileUsingFileReference( baFlvEncoder.byteArray );</p>
<p>baFlvEncoder.kill(); // for garbage collection<br />
[/as3]</p>
<p>[B] To encode an FLV directly to a local file (in AIR), instantiate <code>FileStreamFlvEncoder</code> with a <code>File</code> reference, and open up the exposed <code>FileStream</code>, and then close it when you&#8217;re all done:</p>
<p>[as3]<br />
var myFile:File = File.documentsDirectory.resolvePath(&#8220;video.flv&#8221;);<br />
var fsFlvEncoder:FileStreamFlvEncoder = new FileStreamFlvEncoder(myFile, myFrameRate);<br />
fsFlvEncoder.fileStream.openAsync(myFile, FileMode.UPDATE);</p>
<p>fsFlvEncoder.setVideoProperties(myWidth, myHeight, VideoPayloadMakerAlchemy);<br />
fsFlvEncoder.setAudioProperties(BaseFlvEncoder.SAMPLERATE_44KHZ, true, false, true);</p>
<p>fsFlvEncoder.start();</p>
<p>fsFlvEncoder.addFrame(myBitmapData, myAudioByteArray);<br />
fsFlvEncoder.addFrame(myBitmapData, myAudioByteArray); // etc.</p>
<p>fsFlvEncoder.updateDurationMetadata();</p>
<p>fsFlvEncoder.fileStream.close();</p>
<p>fsFlvEncoder.kill();<br />
[/as3]</p>
<p>A new instance of FlvEncoder should be created for every new FLV to be generated. </p>
<p>If you&#8217;re using the Alchemy version, the SWC lives in <code>leelib/util/flvEncoder/alchemy</code>, so be sure add that folder to your project library path. The C++ code is there as well.</p>
<p>Note that the current Alchemy video encoding routine is being done synchronously, which means that although it&#8217;s much faster than the regular AS3 version, the main Flash thread must still wait for the Alchemy encoding to be done before continuing. An asynchronous version would allow for a real-time encoding scenario that is more flexible and probably with less &#8216;dropouts&#8217;, and would probably prompt the need an internal queuing system. Anyway, this warrants further development.</p>
<p><strong>- <a href="https://github.com/zeropointnine/leelib" target="_blank">Source code</a></strong> (Github)</p>
<p class="creacom">Licensed under a <a href="http://creativecommons.org/licenses/by/3.0/" rel="license" target="_blank">Creative Commons Attribution 3.0 License</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeropointnine.com/blog/updated-flv-encoder-alchem/feed/</wfw:commentRss>
		<slash:comments>46</slash:comments>
		</item>
		<item>
		<title>Maze Generation Algorithm</title>
		<link>http://www.zeropointnine.com/blog/maze-generation-algorithm/</link>
		<comments>http://www.zeropointnine.com/blog/maze-generation-algorithm/#comments</comments>
		<pubDate>Sat, 12 Feb 2011 09:03:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[c++]]></category>
		<category><![CDATA[openFrameworks]]></category>
		<category><![CDATA[processing]]></category>
		<category><![CDATA[sourcecode]]></category>

		<guid isPermaLink="false">http://www.zeropointnine.com/blog/?p=788</guid>
		<description><![CDATA[A couple months ago, while I was still a full-time student, which did not last very long, but that&#8217;s another story, I created a maze generator as a way to learn some C++, now posted here just for the fun of it. I started with a description of the algorithm found on Wikipedia, worked it [...]]]></description>
			<content:encoded><![CDATA[<p>A couple months ago, while I was still a full-time student, which did not last very long, but that&#8217;s another story, I created a maze generator as a way to learn some C++, now posted here just for the fun of it.</p>
<p>I started with a description of the algorithm found on <a href="http://en.wikipedia.org/wiki/Maze_generation_algorithm" target="_blank">Wikipedia</a>, worked it out in Processing (with 2D, 3D, and isometric views added as a bonus), and then ported it to C++ using openFrameworks for the basic display action.</p>
<p>Presumably it could be used as the start of a game-like concept, if so inclined.</p>
<p>- <a href="http://www.zeropointnine.com/blog/assets_code/MazeGenProcessing.zip">Processing</a> (source + Win/Mac executables)<br />
- <a href="http://www.zeropointnine.com/blog/assets_code/MazeGenCpp.zip">C++/oF</a> (source + Windows executable)<br />
<br/></p>
<iframe src='http://player.vimeo.com/video/15280326?title=1&amp;byline=1&amp;portrait=1' width='560' height='560' frameborder='0'></iframe><br />
<br/><br />
<iframe src='http://player.vimeo.com/video/15681233?title=1&amp;byline=1&amp;portrait=1' width='560' height='560' frameborder='0'></iframe>
]]></content:encoded>
			<wfw:commentRss>http://www.zeropointnine.com/blog/maze-generation-algorithm/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Announcing &#8220;min3D&#8221;, a 3D framework for Android</title>
		<link>http://www.zeropointnine.com/blog/a-3d-framework-for-android-min3d/</link>
		<comments>http://www.zeropointnine.com/blog/a-3d-framework-for-android-min3d/#comments</comments>
		<pubDate>Thu, 06 May 2010 03:32:31 +0000</pubDate>
		<dc:creator>Lee</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[opengl es]]></category>
		<category><![CDATA[sourcecode]]></category>

		<guid isPermaLink="false">http://www.zeropointnine.com/blog/?p=573</guid>
		<description><![CDATA[Why yes, that is the Earth revolving around the planet JupiterView the code for this example.Note how the &#8220;onEnterFrame&#8221; function is only 8 lines long. Update:Download min3D sample app(Android v1.5 or higher) This post announces a 3D framework/library-in-progress I&#8217;ve been writing for Android, written in Java with OpenGL ES. Between the names min3d, modest3d, and [...]]]></description>
			<content:encoded><![CDATA[<div class="vimeoBox" style="padding-left:20px; padding-top:20px; padding-bottom:20px; width:264px;"><iframe src='http://player.vimeo.com/video/11508316?title=1&amp;byline=1&amp;portrait=1' width='264' height='440' frameborder='0'></iframe>
<div><em>Why yes, that is the Earth revolving around the planet Jupiter</em><br/><br/><a href="http://code.google.com/p/min3d/source/browse/trunk/sampleProjects/min3dSampleProject1/src/min3d/sampleProject1/ExampleRotatingPlanets.java" target="_blank">View the code for this example.</a><br/>Note how the &#8220;onEnterFrame&#8221; function is only 8 lines long.</div>
</div>
<div style="text-align:center;"><br/><b>Update:</b><br/><a href="http://code.google.com/p/min3d/downloads/list" target="blank">Download min3D sample app</a><br/>(Android v1.5 or higher)</div>
<p>This post announces a 3D framework/library-in-progress I&#8217;ve been writing for Android, written in Java with OpenGL ES. Between the names <em>min3d</em>, <em>modest3d</em>, and <em>llama3d</em>, I&#8217;ve gone with <em>&#8220;min3d&#8221;</em> for being the least self-deprecating while still conveying an appropriate level of expectation that I&#8217;m comfortable with. :)</p>
<p>I&#8217;ve gone legit by putting it up on <a href="http://code.google.com/p/min3d/" target="_blank"><b>Google Code</b></a> (first time for everything, etc.). While just an early build, it should at the very least be useful for educational purposes if like me you&#8217;re just starting down the Android path. </p>
<p>My aim while building this was to make a library that required no extra massaging of model data on its way to being used by OpenGL. To that end, data can be created and manipulated directly on the <code>ByteBuffers</code> that are used by OpenGL, without the need for any intermediating (ie, redundant) data structures. And hopefully wrapped in such a way that&#8217;s still relatively easy to use.</p>
<p>But this approach also imposes some important restrictions. The maximum number of vertices and faces of an <code>Object3d</code> is fixed after instantiation, and the dynamic addition/removal of vertex or face elements is currently not supported. If/when implemented, these operations will have to be much more costly than, say, with a linked list. But unavoidable, as far as I can tell.</p>
<p>Here&#8217;s what&#8217;s currently implemented through the API (all conventional stuff&#8230;)</p>
<p><span id="more-573"></span></p>
<ul class="normalList">
<li>Vertex index lists</li>
<li>Per-vertex colors</li>
<li>Vertex normals</li>
<li>Texture mapping</li>
<li>Light source (just the one, for now)</li>
<li>Camera class, with view frustrum settings</li>
<li>Object scale, euler rotation, and translation properties as expected</li>
<li>Object children that inherit parent&#8217;s transform properties</li>
<li>Ability to render a subset of an object&#8217;s list of faces</li>
<li>Triangle or point rendermodes (just the two, for now)</li>
<li>A few canned object primitives</li>
</ul>
<p>Code examples showing how to actually use &#8220;min3d&#8221; in its current form can be found through the <a href="http://code.google.com/p/min3d/" target="_blank">project home page</a> on Google Code by checking out the source with SVN, and going through the <a href="http://code.google.com/p/min3d/source/browse/#svn/trunk/sampleProjects/min3dSampleProject1/src/min3d/sampleProject1" target="_blank">sampleProjects/</a> directory.</p>
<p>In the immediate future, I&#8217;d like to be able to at least add a light manager and a 3d-file format importer, and definitely test and debug more thoroughly. If anyone is interested in collaborating on or even picking up this project, <a href="mailto:felarca_@_yahoo_dot_com">please let me know</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeropointnine.com/blog/a-3d-framework-for-android-min3d/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Using NativeProcess in AIR 2 for screencaps</title>
		<link>http://www.zeropointnine.com/blog/using-nativeprocess-in-air-2-for-screencaps/</link>
		<comments>http://www.zeropointnine.com/blog/using-nativeprocess-in-air-2-for-screencaps/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 02:15:45 +0000</pubDate>
		<dc:creator>Lee</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[dot net]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[sourcecode]]></category>

		<guid isPermaLink="false">http://www.zeropointnine.com/blog/?p=498</guid>
		<description><![CDATA[Download installable AIR fileRequires AIR 2 Beta 2 Runtime +Windows .NET v3.5 My aim here was to get familiar with AIR 2&#8242;s new capability of interacting with external processes&#8217; standard streams. One useful way of learning how to use a new feature is to proceed directly to trying to abuse it. To that end, this [...]]]></description>
			<content:encoded><![CDATA[<div class="paragraph1">
<div class="imageright"><a href="/blog/assets/NativeProcessTest_Installer.zip"><img border="0" src="/blog/assets/NativeProcessTest_t.jpg" alt="Thumbnail" /><br/><br/><strong>Download installable AIR file</a></strong><br/><em style="font-size:10px">Requires AIR 2 Beta 2 Runtime +<br/>Windows .NET v3.5</em></div>
<p>My aim here was to get familiar with AIR 2&#8242;s new capability of interacting with external processes&#8217; standard streams.</p></div>
<p>One useful way of learning how to use a new feature is to proceed directly to trying to abuse it. </p>
<p>To that end, this AIR application takes in a fairly continuous stream of uncompressed binary image data from a native process&#8217; standard output. My hope was to get real-time screen capture updates into AIR at a decent frame rate.</p>
<p>Details and source code after the break&#8211;</p>
<p><span id="more-498"></span></p>
<p><strong>The native process</strong></p>
<p>For my &#8220;native process,&#8221; I created a Windows .NET application written in C#. When asked, it takes a screen capture of the desktop and sends the image data through the process&#8217; standard output. For various reasons, I chose to set it up as a Windows form rather than as a plain vanilla console or as a real system service. The <a href="/blog/assets_code/NativeProcessTest_Form1.cs.txt" target="_blank">relevant C# code</a> is only a few dozen lines long. One interesting function there is <code>bitmapToBytes()</code>, which converts a bitmap into a byte array in the correct format for Flash to be able to apply it directly to a BitmapData without any further (costly) conversion. </p>
<p><strong>The AIR application</strong></p>
<p>On the &#8220;client-side,&#8221; the Flash AIR application has little to do. It simply sends a command to the native process, telling it to take a screen grab, along with image dimension and offset parameters. Because the client takes in the resulting stream of data in packets whose length should not be assumed to be of any given size, it needs to know where in the data a new image starts and where it ends. So it checks the stream for an arbitrary 4-byte start code as well as a termination code. When the transfer is complete, it just applies the resulting data, collected over time into a ByteArray, using <code>BitmapData.setPixels()</code>. It then requests a new image, and so on.</p>
<p><strong>Performance considerations</strong></p>
<p>On a mid-range quad-core PC using 1280&#215;1024 images (5MB per uncompressed frame), I&#8217;m getting about 8 frames per second, or 125ms per frame. The time it takes for the 5MB image to transfer through the standard stream is about 65ms, or 50% of the total time for one iteration; without setting up an honest benchmark test, it&#8217;d be unfair and/or impolitic to declare that AIR represents a bottleneck here, so &#8230; yeah.</p>
<p>The AIR app eats up about 2/3 of one CPU core using the runtime&#8217;s main application thread. The remaining 1/3 represents the amount of time the AIR app has to wait while the native process constructs the screengrab. If the app were re-architected in such a way that the native process always has a new screencap queued up and ready to send &#8211; leading to little or no idle time between request and response &#8211; the AIR app would easily soak a full CPU core. Since the AIR app is doing little of significance besides reading the process&#8217;s standard stream and collecting that info into a byte array, it appears that merely handling large amounts of stdout data is quite costly. </p>
<p>Of course, AIR 2 isn&#8217;t even final yet. Nevertheless, I thought these preliminary findings were interesting. (This build targets Beta 2, which is the most recent public beta of AIR 2; compiling and running it against the most recent non-public beta of the SDK and runtime dated April 9, 2010 gave the same results.)</p>
<p><strong>Source files</strong></p>
<p>Setting up a native process for use with AIR 2 is well documented so I didn&#8217;t bother commenting on that here. However, the included source is I believe a good starting point for adapting to whatever native process craziness you may be cooking up&#8230; </p>
<div style="margin-left:35px; padding-top:10px; padding-bottom:10px;">
<a href="/blog/assets/NativeProcessTest_Installer.zip"><strong>AIR application</strong></a> (requires <a href="http://labs.adobe.com/downloads/air2.html" target="_blank">AIR 2 Beta 2 runtime</a> and <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=333325fd-ae52-4e35-b531-508d977d32a6&#038;displaylang=en" target="_blank">.NET v3.5 for Windows</a>)<br />
<a href="/blog/assets_code/NativeProcessTest.as.txt" target="_blank"><strong>Main AS3 class file</strong></a><br />
<a href="/blog/assets_code/NativeProcessTest_Form1.cs.txt" target="_blank"><strong>Main C# class file </strong></a><br />
<a href="/blog/assets_code/NativeProcessTest_projectfiles.zip"><strong>Full project source</strong></a> (Flash Builder 4 + Visual Studio 2008)
</div>
<p>For another implementation of AIR 2 screen capture, see <a href="http://corlan.org/2009/11/30/magnifying-glass-air-2-application-or-how-to-communicate-with-a-java-program-from-air/" target="_blank">this post by Mihai Corlan</a>, also with source, using Java. There are also a few other related examples out there as well.</p>
<p class="creacom">Licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/" target="_blank">Creative Commons Attribution 3.0 License</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeropointnine.com/blog/using-nativeprocess-in-air-2-for-screencaps/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Keyboard Mousebutton Replacement Utility (.NET)</title>
		<link>http://www.zeropointnine.com/blog/keyboard-mousebutton-replacement-utility-net/</link>
		<comments>http://www.zeropointnine.com/blog/keyboard-mousebutton-replacement-utility-net/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 05:25:38 +0000</pubDate>
		<dc:creator>Lee</dc:creator>
				<category><![CDATA[dot net]]></category>
		<category><![CDATA[sourcecode]]></category>
		<category><![CDATA[Lots of work]]></category>
		<category><![CDATA[not much payoff]]></category>

		<guid isPermaLink="false">http://www.zeropointnine.com/blog/?p=387</guid>
		<description><![CDATA[This one&#8217;s pretty niche: A small Windows utility that emulates the left and right mousebuttons using the keyboard. Specifically, using the right Windows key and the right Alt key. Why? Because I use a MacBook Pro running exclusively in PC-mode, and I can&#8217;t stand how the mouseclick is implemented with its button-less trackpad. So yeah, [...]]]></description>
			<content:encoded><![CDATA[<div class="paragraph1">
<div class="imageright"><img src="/blog/assets/KeyboardMouseButtons_t.png" alt="Screenshot" /></div>
<p>This one&#8217;s pretty niche: A small Windows utility that emulates the left and right mousebuttons using the keyboard. Specifically, using the right Windows key and the right Alt key.
</p></div>
<p>Why? Because I use a MacBook Pro running exclusively in PC-mode, and I can&#8217;t stand how the mouseclick is implemented with its button-less trackpad. So yeah, pretty niche&#8230;</p>
<p>Sorry, no UI to change the hotkey assignments. If you&#8217;re comfortable with C#.NET, the source code is included in the zip file. It may be useful to examine if you&#8217;re interested in learning (1) how to capture keystrokes globally in Windows or (2) how to generate mouse operations programmatically, using some dreadful-looking Windows API interop code that I tried to learn as little as possible about in order to get to work.</p>
<p><a href="/blog/assets/KeyboardMouseButtons.zip"><b>Download</b></a> (source included)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeropointnine.com/blog/keyboard-mousebutton-replacement-utility-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Complex Spotlight Shadow Caster for Papervision3D</title>
		<link>http://www.zeropointnine.com/blog/complex-spotlight-shadow-caster-in-papervision3d/</link>
		<comments>http://www.zeropointnine.com/blog/complex-spotlight-shadow-caster-in-papervision3d/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 03:01:32 +0000</pubDate>
		<dc:creator>Lee</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[flash 3d]]></category>
		<category><![CDATA[sourcecode]]></category>

		<guid isPermaLink="false">http://www.zeropointnine.com/blog/?p=366</guid>
		<description><![CDATA[Simulates the projection of shadows coming from a spotlight light source onto irregular surfaces. In the supplied example, an animated MD2 model (from Quake 2) is casting a shadow onto the inside of a sphere. Supported parameters include shadow color, alpha, blur, falloff and texture map size, as well as position, rotation and field of [...]]]></description>
			<content:encoded><![CDATA[<div class="paragraph1">
<div class="imageright"><img style="cursor: pointer" onclick="javascript:showBox('shadowcaster',780,780, '444444',this);" src="/blog/assets/shadowcaster_t.jpg" alt="Thumbnail - Click me" /></div>
<p>Simulates the projection of shadows coming from a spotlight light source onto irregular surfaces. In the supplied example, an animated MD2 model (from Quake 2) is casting a shadow onto the inside of a sphere. Supported parameters include shadow color, alpha, blur, falloff and texture map size, as well as position, rotation and field of view. This evolves out of the projection work posted previously.</p></div>
<p><strong>Source:</strong></p>
<p><a href="/blog/assets_code/SpotlightShadowCasterManager.as.txt" target="_blank">SpotlightShadowCasterManager.as</a></p>
<p><strong>Usage:</strong></p>
<p>After instantiating the manager &#8211;</p>
<pre>	_shadowCaster = new SpotlightShadowCasterManager();</pre>
<p>&#8211; assign one or more DisplayObject3D&#8217;s that will block the light from the spotlight:</p>
<pre>	_shadowCaster.registerShadowCasterObject(myMesh);</pre>
<p>Then register one or more meshes that can have shadows cast upon it with <code>registerShadowCasterObject</code>. As the second argument, you must supply a <code>BitmapMaterial</code> utilized by the mesh on which the manager will draw the shadows. Usually, you&#8217;ll want to create a <code>CompositeMaterial</code>, with the <code>BitmapMaterial</code> most likely at the top of the stack. It might look something like this:</p>
<pre>	var compositeMaterial = new CompositeMaterial();
	compositeMaterial.addMaterial( new ColorMaterial(0x888888) );
	var mat:BitmapMaterial = new BitmapMaterial( new BitmapData(1,1) );
	// .. the bitmapdata will get overwritten,
	//    but must contain _something_
	var sphere:TriangleMesh3D = new Sphere(compositeMaterial, 1000);

	_shadowCaster.registerShadowReceiverObject(sphere, mat);</pre>
<p>To update the shadow textures, call</p>
<pre>	_shadowCaster.update();</pre>
<p>&#8211; probably in your <code>onEnterFrame</code> or <code>onRenderTick</code> function.</p>
<p>That&#8217;s enough to get going. From there, it&#8217;s just a matter of adjusting the projector&#8217;s position and orientation in relation to the objects in your scene with the properties <code>projectorPosition</code>, <code>projectorPitch</code>, and <code>projectorRoll</code>. Check the source for the various configurable properties like blur, alpha, color, etc.</p>
<p><strong>Limitations, bugs:</strong></p>
<p><span id="more-366"></span>- As described above, objects must be manually assigned to be either a &#8216;caster&#8217; or a &#8216;receiver&#8217;. These roles aren&#8217;t determined dynamically by the class itself.</p>
<p>- Only one level of shadows is supported. Adding an arbitrary number wouldn&#8217;t be difficult, just cumbersome to manage under the current system, and increasingly expensive.</p>
<p>- Unfortunately, a &#8216;shadow receiver&#8217; object can&#8217;t have its own texture in addition to the one used to cast shadows onto, at least not in a way that looks decent. The reason is that a 3d object in Papervision3D has only one set of UV texture data and the shadow texture overwrites this with every update.</p>
<p>- There&#8217;s undoubtedly a less expensive way to do the raycasting/projection in the main math routine in the private function <code>updateMesh</code>. If you&#8217;re adept at this kind of thing, please send your improvements!</p>
<p>- Ugly and obvious artifacts show up on the &#8216;projectable&#8217; textures when the spotlight is rotated 90 degrees away them. (You may have already noticed this in the previous two projection experiment posts).  Again, I&#8217;d love any solutions anyone has for this.</p>
<p class="creacom">Licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/" target="_blank">Creative Commons Attribution 3.0 License</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeropointnine.com/blog/complex-spotlight-shadow-caster-in-papervision3d/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>An SEO implementation for Flash</title>
		<link>http://www.zeropointnine.com/blog/an-seo-implementation-for-flash/</link>
		<comments>http://www.zeropointnine.com/blog/an-seo-implementation-for-flash/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 15:37:28 +0000</pubDate>
		<dc:creator>Lee</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[sourcecode]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.zeropointnine.com/blog/?p=299</guid>
		<description><![CDATA[I recently added SEO to my current (Flash-based) portfolio site, which I did as an experiment more than for any particular use value. You can navigate the HTML &#8216;back-end&#8217; pages starting from here, if interested. I figured I should jot down my findings on how it can be done, for the record. I. Client Side [...]]]></description>
			<content:encoded><![CDATA[<p>I recently added SEO to my current (Flash-based) <a href="http://portfolio2008.felar.ca" target="_blank">portfolio site</a>, which I did as an experiment more than for any particular use value. You can navigate the HTML &#8216;back-end&#8217; pages starting <a href="http://portfolio2008.felar.ca/?noflash=true" target="_blank">from here</a>, if interested. I figured I should jot down my findings on how it can be done, for the record.</p>
<p><b>I. Client Side</b></p>
<p>On the Flash end, two requirements:</p>
<div class="paragraph1">
<div class="imageright"><a href="http://portfolio2008.felar.ca/#/work/evb/stives_elements/" target="_blank"><img src="/blog/assets/seo_flashpage_t.jpg" border="0" /></a>
<div class="altlink">Original page view, in Flash</div>
<div class="altlink"><a href="http://portfolio2008.felar.ca/work/evb/stives_elements/" target="_blank"><img src="/blog/assets/seo_htmlpage_t.jpg" vspace="4" border="0" /></a><br/>SEO-friendly HTML page, drawing on the same data</div>
</div>
</div>
<p><b>(A)</b> Your site must implement deeplinking, presumably using <a href="http://www.asual.com/swfaddress/" target="_blank">SWFAddress</a>, such that every page view has its own URL path. And your shell class must be intelligent enough to go directly to any given deeplinkable page view on startup via the URL deeplink.</p>
<p>(<i>Sidenote:</i> While not strictly necessary from an SEO standpoint, having gone that far, you&#8217;ll probably want all changes to the page view to be driven by the SWFAddress URL-change event, rather than directly by user events like mouse clicks, etc. Which will force you to throw your familiar, tried-and-true coding patterns out the window. And potentially, your laptop thereafter. But is beyond the scope of this entry. ;)</p>
<p><b>(B)</b> Your site should use an external data source that describes the site structure and contains the site&#8217;s text content, as well as, typically, image and/or video URL&#8217;s and the like. Usually, this would be a well structured, static XML file whose node structure corresponds to the site&#8217;s actual page structure. The deeplink &#8216;crumbs&#8217; should be included therein as well &#8211; as an attribute of each node, for example. (Extra points for using a database or a CMS instead). And it goes without saying that your Flash should be building its site structure, nav, and page content dynamically using all of the above.</p>
<p><span id="more-299"></span></p>
<p><br/><b>II. Server Side</b></p>
<p>On the server side, nothing too fancy. You want to create a script that parses the XML tree, constructs and writes out an HTML file for every deeplinked page in your site. You&#8217;ll run the script every time you make changes to the data, or create a chron job. So in the end, there&#8217;s nothing very &#8216;dynamic&#8217; happening on the back end, just using a script to create static HTML files from a static XML file. (* Extra points for using XSL to magically transform your XML into ready-to-use HTML pages, but since XSL makes my head hurt, I just procedurally concatenated lots and lots of HTML tags together to form one big string&#8230;)</p>
<p>The directory path for each generated &#8220;index.html&#8221; page should correspond to the deeplink used in your Flash (everything after the hash mark). So if you have a page whose URL is:</p>
<div style="margin-left:30px;font-size:11px;">     http://www.mylanguishingportfoliosite.com/#/work/2009/frivolous_viral_microsite/</div>
<p>- your script should create a corresponding HTML page whose filename is</p>
<div style="margin-left:30px;font-size:11px;">     [web root]/work/2009/frivolous_viral_microsite/index.html</div>
<p>Each HTML page should include all the text content for a given page view, since SEO is our goal, after all. Hopefully, you have a page title attribute on your XML nodes that you can leverage as well. Maybe you want to add some keyword metadata in there, too.</p>
<p>The last thing you want to do is have each of your generated html pages auto-redirect to its Flash equivalent using Javascript, or at least display a prominent link for the user to do it for themselves (Ie, strip &#8220;index.html&#8221; off the end of the URL and insert &#8220;/#&#8221; after the domain name). Personally, I chose to do the latter, since I took the trouble to create HTML that could stand &#8216;on its own&#8217;, without the Flash, if necessary. Your pages should link to each other as well; otherwise, the web crawlers may not have a way to get to them all.</p>
<p>So, here&#8217;s the <a href="/blog/assets_code/html_page_generator.php_.txt" target="_blank">PHP script</a> I wrote for my site which may help concretize the procedure described above. And the <a href="http://portfolio2008.felar.ca/assets/content.xml" target="_blank">XML file</a> for your reference, used by both the the Flash and the PHP based on their respective agendas. And for the hell of it, my <a href="http://www.google.com/search?q=hellogoogle666&#038;filter=0" target="_blank">magic keyword</a>, inserted into the HTML to easily verify if/when they were becoming visible to Google. xD</p>
<p class="creacom">Licensed under a <a href="http://creativecommons.org/licenses/by/3.0/" rel="license" target="_blank">Creative Commons Attribution 3.0 License</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeropointnine.com/blog/an-seo-implementation-for-flash/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Faceted Crystal Ball</title>
		<link>http://www.zeropointnine.com/blog/faceted-crystal-ball/</link>
		<comments>http://www.zeropointnine.com/blog/faceted-crystal-ball/#comments</comments>
		<pubDate>Tue, 03 Mar 2009 18:00:34 +0000</pubDate>
		<dc:creator>Lee</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[flash 3d]]></category>
		<category><![CDATA[sourcecode]]></category>

		<guid isPermaLink="false">http://www.zeropointnine.com/blog/?p=261</guid>
		<description><![CDATA[Or at least, that&#8217;s the best easy analogy to describe it. Gist: The color of each triangle in the mesh is obtained by averaging the pixel colors of the underlying image at the screen positions under each vertex as well as at the triangles&#8217; center point. Some FlatShader-like lighting is used to add a little [...]]]></description>
			<content:encoded><![CDATA[<div class="paragraph1">
<div class="imageright"><img src="/blog/assets/facets_t.jpg" onclick="javascript:showBox('facets',640,480,'000000',this);" alt="Thumbnail - Click me" style="cursor: pointer" /></div>
</div>
<p>Or at least, that&#8217;s the best easy analogy to describe it.</p>
<p><em>Gist:</em> The color of each triangle in the mesh is obtained by averaging the pixel colors of the underlying image at the screen positions under each vertex as well as at the triangles&#8217; center point. Some FlatShader-like lighting is used to add a little more three-dimensionality. Finally, a BlurFilter is applied to the source image to keep the transitions between colors from feeling too abrupt.</p>
<p>Source code: <a href="/blog/assets_code/PvColorFacets.as.txt"  target="_blank">PvColorFacets.as</a></p>
<p class="creacom">Licensed under a <a href="http://creativecommons.org/licenses/by/3.0/" rel="license" target="_blank">Creative Commons Attribution 3.0 License</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeropointnine.com/blog/faceted-crystal-ball/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Webcam Green Screen Effect w/ Pixel Bender</title>
		<link>http://www.zeropointnine.com/blog/webcam-green-screen-effect-w-pixel-bender/</link>
		<comments>http://www.zeropointnine.com/blog/webcam-green-screen-effect-w-pixel-bender/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 16:36:59 +0000</pubDate>
		<dc:creator>Lee</dc:creator>
				<category><![CDATA[flash]]></category>
		<category><![CDATA[sourcecode]]></category>

		<guid isPermaLink="false">http://www.zeropointnine.com/blog/?p=194</guid>
		<description><![CDATA[A green-screen/chroma key effect utilizing Pixel Bender. With this version, the live video is compared against a reference image rather than a static color. Additionally, the alpha of the output is graduated based on the color difference between the base image and the incoming video (rather than just being either &#8216;on&#8217; or &#8216;off&#8217;). Both of [...]]]></description>
			<content:encoded><![CDATA[<div class="paragraph1">
<div class="imageright"><img src="/blog/assets/greenscreen_t.jpg" onclick="javascript:showBox('greenscreen',660,500,'e5e5e5',this);" alt="Thumbnail - Click me" style="cursor: pointer" /></div>
</div>
<p>A green-screen/chroma key effect utilizing Pixel Bender. With this version, the live video is compared against a reference image rather than a static color. Additionally, the alpha of the output is graduated based on the color difference between the base image and the incoming video (rather than just being either &#8216;on&#8217; or &#8216;off&#8217;). Both of these differences may or may not be good for practical use, but can create interesting imagery.</p>
<p>Use the sliders to adjust the cutoff/falloff curve for the alpha. Click &#8220;Reset base image&#8221; to set the base image with which to compare any further changes in the video against. You can also choose your own background image (click &#8220;Browse&#8230;&#8221; at the bottom). Works best against a plain background and presumably best of all with proper lighting against a green background&#8230;</p>
<div style="text-align:right;"><a href="/blog/assets/greenscreen_paper_masked.jpg" target="_blank"><img src="/blog/assets/greenscreen_paper_masked_t.jpg" hspace="2" /></a><a href="/blog/assets/greenscreen_paper_raw.jpg" target="_blank"><img src="/blog/assets/greenscreen_paper_raw_t.jpg" hspace="2" /></a><a href="/blog/assets/greenscreen_interesting.jpg" target="_blank"><img src="/blog/assets/greenscreen_interesting_t.jpg" hspace="2" /></a><a href="/blog/assets/greenscreen_memono.jpg" target="_blank"><img src="/blog/assets/greenscreen_memono_t.jpg" hspace="2" /></a></div>
<p>When I wrote the image processing routine in pure Actionscript, it ran like a slideshow. The Pixel Bender version on a multi-core system runs about 30x faster.</p>
<p>Pixel Bender kernel: <a href="/blog/assets_code/GreenScreenEffect.pbk.txt"  target="_blank">GreenScreenEffect.pbk</a></p>
<p class="creacom">Licensed under a <a href="http://creativecommons.org/licenses/by/3.0/" rel="license" target="_blank">Creative Commons Attribution 3.0 License</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zeropointnine.com/blog/webcam-green-screen-effect-w-pixel-bender/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

