<?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>Da Fish in Sea &#187; actionscript</title>
	<atom:link href="http://www.dafishinsea.com/blog/category/actionscript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dafishinsea.com/blog</link>
	<description>Arrr ! Ya call that programming? Walk the plank now, yarrr..!</description>
	<lastBuildDate>Thu, 26 Aug 2010 11:52:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>drawing in 3D</title>
		<link>http://www.dafishinsea.com/blog/2010/03/13/drawing-in-3d/</link>
		<comments>http://www.dafishinsea.com/blog/2010/03/13/drawing-in-3d/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 03:11:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3d]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[haxe]]></category>

		<guid isPermaLink="false">http://www.dafishinsea.com/blog/2010/03/13/drawing-in-3d/</guid>
		<description><![CDATA[Last year Seb Lee-Delisle posted about how it would be nice to be able to draw in 3D with the same ease as you can draw in 2D, using the flash drawing API. It inspired me to try something similar, but with a different approach. I was looking into WebGL and OpenGL late last year, [...]]]></description>
			<content:encoded><![CDATA[<p>Last year Seb Lee-Delisle posted about how it would be nice to be able to <a href="http://sebleedelisle.com/2009/11/simple-flash-3d-drawing-api/">draw in 3D</a> with the same ease as you can draw in 2D, using the flash drawing API. It inspired me to try something similar, but with a different approach. I was looking into WebGL and OpenGL late last year, and though I got a bit bogged down with my lack of C knowledge, I found I liked the procedural API. The entire scene is actually redrawn every frame. This year I&#8217;ve also been thinking about the Turtle graphics system I once used in school, and how it works in a similar way (albeit in 2D). So I took a stab at creating a simple procedural 3D drawing API, along the lines of OpenGL and Logo. First the demo..</p>
<p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="800" height="600" id="drawCubes"><param name="movie" value="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/haxe/draw3d/DrawCubes.swf" /><param name="quality" value="high"/><param name="bgcolor" value="#000000"/><embed src="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/haxe/draw3d/DrawCubes.swf" quality="high" bgcolor="#000000" width="800" height="600" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed></object></p>
<p> <a href="http://www.adobe.com/go/getflashplayer">flash 10 </a>required </p>
<p>It is currently implemented as a base class which exposes the following methods:</p>
<pre>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; rotate<span style="color: #66cc66;">&#40;</span>angleX, angleY, angleZ<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; draw<span style="color: #66cc66;">&#40;</span>x,y,z<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; move<span style="color: #66cc66;">&#40;</span>x,y,z<span style="color: #66cc66;">&#41;</span><br />
<br />
&nbsp; &nbsp; pushMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; popMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span></div></td></tr></tbody></table></div>
</pre>
<p>The x, y, z values here are relative to the current position. The current position (and rotation) is maintained by the modelViewMatrix. By calling  pushMatrix() you can save the current state and return to it later with popMatrix(). If you have subroutines, it is generally a good idea if they return the modelViewMatrix to the same state. For example in this example the drawSquare() method does this:</p>
<pre>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> drawSquare<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; draw<span style="color: #66cc66;">&#40;</span>100,0,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; rotate<span style="color: #66cc66;">&#40;</span>0,0,90<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; draw<span style="color: #66cc66;">&#40;</span>100,0,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; rotate<span style="color: #66cc66;">&#40;</span>0,0,90<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; draw<span style="color: #66cc66;">&#40;</span>100,0,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; rotate<span style="color: #66cc66;">&#40;</span>0,0,90<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; draw<span style="color: #66cc66;">&#40;</span>100,0,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; rotate<span style="color: #66cc66;">&#40;</span>0,0,90<span style="color: #66cc66;">&#41;</span>;<span style="color: #808080; font-style: italic;">//return to starting orientation</span><br />
<span style="color: #66cc66;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>So this simply draws 4 lines of length 100, rotating 90 degrees around the Z axis. The final rotation isn&#8217;t necessary for the drawing, but it ensures that the state is not changed after the routine is called. To draw a cube, we call the drawSquare routine while rotating and moving in 3D.</p>
<pre>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> drawCube<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//draw cube</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//back</span><br />
&nbsp; &nbsp; drawSquare<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//left</span><br />
&nbsp; &nbsp; pushMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; rotate<span style="color: #66cc66;">&#40;</span>0,90,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; drawSquare<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; popMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//top</span><br />
&nbsp; &nbsp; pushMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; rotate<span style="color: #66cc66;">&#40;</span>-90,0,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; drawSquare<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; popMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//right</span><br />
&nbsp; &nbsp; pushMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; move<span style="color: #66cc66;">&#40;</span>100,0,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; rotate<span style="color: #66cc66;">&#40;</span>0,90,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; drawSquare<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; popMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//bottom</span><br />
&nbsp; &nbsp; pushMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; move<span style="color: #66cc66;">&#40;</span>0,100,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; rotate<span style="color: #66cc66;">&#40;</span>-90,0,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; drawSquare<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; popMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//front </span><br />
&nbsp; &nbsp; pushMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; move<span style="color: #66cc66;">&#40;</span>0,0,-100<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; drawSquare<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; popMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #66cc66;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>finally, to draw the cubes, we call the drawCube() routine inbetween calls to push/popMatrix() and any changes in position we wish to make.</p>
<pre>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; pushMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; drawCube<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; popMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; pushMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; move<span style="color: #66cc66;">&#40;</span>150,0,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; drawCube<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; popMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; pushMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; move<span style="color: #66cc66;">&#40;</span>-150,0,0<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; drawCube<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; popMatrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></td></tr></tbody></table></div>
</pre>
<p>Once you get the hang of this approach, it is quite intuitive, and reduces the need for calculating a lot of 3D coordinates. This is done behind the scenes in the draw() method, which adds the real 3D coordinates to a list of vertices, which ultimately get projected to 2D coordinates. It&#8217;s easy to rotate the objects in the scene by calling rotate() before drawing the objects in the scene.</p>
<p>I&#8217;ve used <a href="http://haxe.org/">Haxe</a> here because of the faster compile time. There is also an earlier ActionScript version which I&#8217;ll link to below. </p>
<h3>Da Code</h3>
<p><a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/haxe/draw3d/DrawCubes.hx">DrawCubes.hx</a></p>
<p><a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/haxe/draw3d/Draw3D.hx">Draw3D.hx</a></p>
<p><a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/experiments/MatrixStack.as">MatrixStack.as</a> (the AS3 prototype)</p>
<p><a href="http://github.com/bigfish/fishpond">GitHub</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dafishinsea.com/blog/2010/03/13/drawing-in-3d/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A 3D heart for Valentine&apos;s Day</title>
		<link>http://www.dafishinsea.com/blog/2010/02/14/a-3d-heart-for-valentines-day/</link>
		<comments>http://www.dafishinsea.com/blog/2010/02/14/a-3d-heart-for-valentines-day/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 14:46:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3d]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[flash]]></category>

		<guid isPermaLink="false">http://www.dafishinsea.com/blog/2010/02/14/a-3d-heart-for-valentines-day/</guid>
		<description><![CDATA[For Valentine&#8217;s Day I&#8217;ve dusted off an idea I initially submitted last year as part of the now defunct 25 Lines ActionScript contest. By tweaking the formula which generates the coordinates of the sphere, I was able to get something that more or less looked like a heart. I was able to get the heart [...]]]></description>
			<content:encoded><![CDATA[<p>For Valentine&#8217;s Day I&#8217;ve dusted off an idea I initially submitted last year as part of the now defunct 25 Lines ActionScript contest. By tweaking the formula which generates the coordinates of the sphere, I was able to get something that more or less looked like a heart. I was able to get the heart modeled and lit within the 25 lines, but could not quite squeeze in the code to animate it. Now, without the limitation of 25 lines, I&#8217;ve done that, as well as optimize the performance using the normal map + PixelBender normal map shader that I used in my <a href="http://www.dafishinsea.com/blog/2009/11/09/lighting-a-3d-object-in-flash-pt-1/">normal map tutorial</a>. Here is the result &#8211; use the sliders to change the direction of the lighting. </p>
<p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="800" height="600" id="heart"><param name="movie" value="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/heart/Heart2.swf" /><param name="quality" value="high"/><param name="bgcolor" value="#000000"/><embed src="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/heart/Heart2.swf" quality="high" bgcolor="#000000" width="800" height="600" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed></object></p>
<p> <a href="http://www.adobe.com/go/getflashplayer">flash 10 </a>required </p>
<h3>How it Was Done</h3>
<p>The mechanics of this are essentially the same as the lighting of a sphere technique described in the normal map tutorial. However, since the shape of the heart is not the same as a sphere, I could not use the sphere formula to generate the normal map. So I just used the same formula to generate the normal map as I did to generate the geometry. For each point on the texture map, I determined the lat/lon of that point, and plugged it in to the formula to get its 3D position. I did the same for the pixel above and to the right. Since we now have three points, we have a triangle, and we can get the normal of the triangle by the cross-product of two of the sides (considered as vectors). This normal gets encoded as a color in the resulting normal map. This is a fairly intensive operation, but since it is only required once at the start, it doesn&#8217;t affect the running performance. I tried to optimize this process by using a PixelBender kernel to generate the normal map, but got some odd results, so returned to more familiar ActionScript territory. Using a shader to generate the normal map will become necessary if the geometry changes a lot.</p>
<p>I also refactored the code a lot so that it&#8217;s not all in one class. I&#8217;ve separated the model, shader and renderer into separate classes, and used a Scene to coordinate them. This is the beginnings of a primitive 3D engine, which I&#8217;ve dubbed DeepSee, so if that goes anywhere I may break it out as a separate project on GitHub.</p>
<h3>Da Code</h3>
<p>
<a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/heart/Heart2.as">Heart2</a> <br/><br />
<a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/deepsee/DeepScene.as">DeepScene</a> <br/><br />
<a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/models/Heart.as">Heart.as</a> <br/><br />
<a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/models/IModel.as">IModel.as</a> <br/><br />
<a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/shaders/NormalMapShader.as">NormalMapShader</a> <br/><br />
<a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/shaders/NormalMapShader.pbk">NormalMapShader.pbk</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dafishinsea.com/blog/2010/02/14/a-3d-heart-for-valentines-day/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting ctags to work with ActionScript and Haxe</title>
		<link>http://www.dafishinsea.com/blog/2010/01/21/getting-ctags-to-work-with-actionscript-and-haxe/</link>
		<comments>http://www.dafishinsea.com/blog/2010/01/21/getting-ctags-to-work-with-actionscript-and-haxe/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 03:51:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[haxe]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.dafishinsea.com/blog/2010/01/21/getting-ctags-to-work-with-actionscript-and-haxe/</guid>
		<description><![CDATA[If you are not a Vim user this post will probably not be of much interest or value&#8230; anyways, I just wanted to document this, for myself as well  
Ctags, specifically exuberant ctags is a code-indexing system that creates files which summarize all the methods and properties in your classes. Its also the name [...]]]></description>
			<content:encoded><![CDATA[<p>If you are not a Vim user this post will probably not be of much interest or value&#8230; anyways, I just wanted to document this, for myself as well <img src='http://www.dafishinsea.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Ctags, specifically <a href="http://ctags.sourceforge.net/">exuberant ctags</a> is a code-indexing system that creates files which summarize all the methods and properties in your classes. Its also the name of the command line utility that performs the indexing on source code and generates the tags files.</p>
<p>Ctags and Vim go hand in hand.. by specifying tags files to use in your .vimrc file, vim will be able to jump to the file where a class, method, or property is defined. Tags are also used for code-completion, and syntax highlighting. </p>
<p>Unfortunately ActionScript is not natively supported by ctags. Fortunately it is not hard to add support for it. I found out <a href="http://www.turdhead.com/2007/10/09/almost-perfect-actionscript-code-browsing-with-jedits-sidekick-panel/">here</a> how to do this for JEdit, but the process is much the same for Vim.</p>
<ol>
<li>
<p>Download Ctags source. I used <a href="http://prdownloads.sourceforge.net/ctags/ctags-5.8.tar.gz">ctags-5.8.tar.gz</a> which worked on my Ubuntu and Mac. I just put it in $HOME/ctags/ and extracted it with &#8216;tar zxvf ctags-5.8.tar.gz&#8217;</p>
</li>
<li>
<p>Ok , go into the source directory (ctags-5.8 or whatever your version is)</p>
</li>
<li>
<p>Add this <a href="https://github.com/bigfish/myvimfiles/raw/master/ctags/ctags-5.8/actionscript.c">actionscript.c</a> file into the source directory (you&#8217;ll need to Save As&#8230; actionscript.c, as github doesn&#8217;t seem to have a per-file download link). I found that the version linked the JEdit example did not work in Vim, so I modified the RegEx expressions in it so that they produced more standard tags.</p>
</li>
<li>
<p>In source.mak, add a line that says &#8220;actionscript.c \&#8221; under SOURCES and &#8220;actionscript.$(OBJEXT) \&#8221; under OBJECTS.</p>
</li>
<li>
<p>In parsers.h, we need to add the following line under #define PARSER_LIST:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ActionScriptParser, \</div></div>
</pre>
<p>(an easy way to make these changes is just copy the line and edit the language name)</p>
</li>
<li>
<p>Build it. Do the usual</p>
<p>./configure<br />
make</p>
</li>
</ol>
<p>You may need to do a &#8216;make clean&#8217; first to remove any previous builds.</p>
<ol>
<li>Try &#8216;./ctags &#8211;list-languages&#8217;, and actionscript one should show up. Then if looks good, go ahead with the final &#8217;sudo make install&#8217;. Thats it.</li>
</ol>
<p>Now for usage &#8230; to build a tags file for a AS3 project in a &#8217;src&#8217; folder, just do the following:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ctags -R -f tags path/to/src</div></div>
</pre>
<p>Eg. I made a tags file for the Flex SDK:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ctags -R -f ${FLEX_HOME}/frameworks/projects/framework/src/tags ${FLEX_HOME}/frameworks/projects/framework/src</div></div>
</pre>
<p>ctags may not be happy about generating a tags file over an existing file, so you may need to remove a previous one first. It may also warn about some null references in source code.. this doesn&#8217;t seem to matter.</p>
<p>Then I added the line </p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">set tags+=$FLEX_HOME/frameworks/projects/framework/src/tags</div></div>
</pre>
<p>to my .vimrc, and I can jump to any Flex SDK file by ctrl-] on the name of a class, method, or property. (ctrl-t jumps back). I can also recommend the <a href="http://vim-taglist.sourceforge.net/">taglist plugin</a>. This instantly makes tags for your current file and shows the symbols (organized by type) in a window split.</p>
<p>I also found that it was easy to add support for Haxe, by renaming a few things in the actionscript.c file and renaming it haxe.c (and making the other additions to sources.mak and parsers.h). You can probably figure it our yourself, or you can download the added and patched files here:</p>
<p><a href="http://www.dafishinsea.com/downloads/ctags_as3_haxe_patched_files.tar.gz">ctags_as3_haxe_patched_files.tar.gz</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.dafishinsea.com/blog/2010/01/21/getting-ctags-to-work-with-actionscript-and-haxe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AR you Serious?</title>
		<link>http://www.dafishinsea.com/blog/2010/01/16/ar-you-serious/</link>
		<comments>http://www.dafishinsea.com/blog/2010/01/16/ar-you-serious/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 03:37:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3d]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[flash]]></category>

		<guid isPermaLink="false">http://www.dafishinsea.com/blog/2010/01/16/ar-you-serious/</guid>
		<description><![CDATA[Using Augmented Reality with native Flash 3D (ie. no 3D library)
Augmented Reality (AR) was one of the big things to appear on the flash scene last year. AR has been around for a while, but it new in flash&#8230; The FLARToolkit, is an ActionScript port (by Saqoosha, whom I got to see at FITC last [...]]]></description>
			<content:encoded><![CDATA[<h2>Using Augmented Reality with native Flash 3D (ie. no 3D library)</h2>
<p><a href="http://en.wikipedia.org/wiki/Augmented_reality">Augmented Reality</a> (AR) was one of the big things to appear on the flash scene last year. AR has been around for a while, but it new in flash&#8230; The <a href="http://www.libspark.org/wiki/saqoosha/FLARToolKit/en">FLARToolkit</a>, is an ActionScript port (by Saqoosha, whom I got to see at FITC last year) of a Java AR library (NyARToolkit) IIRC, which was itself derived from the original C version (ARToolkit).</p>
<p>As an interesting aside: ARToolkit isn&#8217;t the only AR library implemented in C, though it was the first&#8230; there is also <a href="http://www.artag.net/">ARTag</a> which &#8220;uses more complex image processing and digital symbol processing to achieve a higher reliability and immunity to lighting&#8221;. For the limited processing power of Flash, ARToolkit was probably a good start, but perhaps some smart people may be able to enhance its recognition by improving the algorithms.</p>
<p>When I tried to use FLARToolkit, I&#8217;ll admit I had some trouble, as it seemed rather complex and not very well documented (at least not in English). But fortunately I found <a href="http://words.transmote.com/wp/flarmanager/">FLARManager</a> which makes setting up an AR project in Flash a lot simpler. It also provides some <a href="http://www.insideria.com/2009/07/flartoolkit-and-flarmanager.html">optimizations to the recognition process</a>. </p>
<p>However I feel it could be made still be simpler, and I&#8217;m working on that.. although the code still needs some refactoring, I have it basically working with a simple animated butterfly, which is simply a couple of bitmaps with Y rotations applied to them. The trick is to get the matrix that FLARManager gives you back when a marker is recognized, and apply that to your Sprite with 3D content. To use the app, you need to:</p>
<ol>
<li>
<p>make sure you have a webcam attached to your computer and turned on. Most macs have them built-in by default. Don&#8217;t use any other application which uses the camera at the same time or it won&#8217;t work&#8230; thus you can also only run one AR enabled website at a time.</p>
</li>
<li>
<p>print out a AR Marker ( see <a href="http://transmote.com/codeshare/FLARManager/deploy/FLARManager_v061/resources/flar/patterns/">here</a> ) &#8212; right click and download any of the .png files or the .pdf, if you want a whole bunch at once, and print on white paper. At a pinch, you can use a black rectangle drawn on paper, as I did in the video below.</p>
</li>
<li>
<p>Go <a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/ar/ButtARfly.swf">here</a> for the AR Butterfly (but finish reading instructions first <img src='http://www.dafishinsea.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
</li>
<li>
<p>When the flash app starts, it will prompt you to allow access to the camera&#8230; click the &#8216;allow&#8217; button. Now I have found this settings thingy to be very glitchy (it can also be accessed by right clicking on a flash movie and selecting &#8216;Settings&#8230;&#8217;). On my MacBook, I found it took a long time for the dialog to go away after clicking the &#8216;allow button&#8217;. I&#8217;ve also noticed similar problems on Linux. If you&#8217;re having trouble with it you can enable the site permission to access the camera by going here:<br />
<a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager06.html">flash player global settings</a><br />
Then you&#8217;ll need to find this site in the long list, select it, and click &#8216;always allow access&#8217; for the camera. That way you won&#8217;t be bothered by the buggy dialog anymore (at least on this site). </p>
</li>
<li>
<p>Once you can see the output of the camera in the app, make sure you have decent lighting, hold up the marker to the camera, and adjust position so that there is enough contrast, but also no glare, as FLARToolkit does not handle that very well. Also make sure nothing is in front of the marker, breaking the outlines, or it won&#8217;t detect (this is something that ARTag can apparently handle). You should also not move too fast, or have shaky hands&#8230; If you&#8217;re lucky, you&#8217;ll see something like this:</p>
</li>
</ol>
<p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="640" height="480" id="buttARfly"><param name="movie" value="http://www.dafishinsea.com/videos/ButtARfly.swf" /><param name="quality" value="high"/><param name="bgcolor" value="#000000"/><embed src="http://www.dafishinsea.com/videos/ButtARfly.swf" quality="high" bgcolor="#000000" width="640" height="480" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed></object></p>
<p> <a href="http://www.adobe.com/go/getflashplayer">flash 10 </a>required </p>
<p>I noticed that the z-sorting on the butterly wings is inverted in this video&#8230; will have to sort that out. I&#8217;ll post a link to the code later, once it is a bit more polished. I have several ideas for AR applications, which I&#8217;ll hopefully get a chance to work on soon&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dafishinsea.com/blog/2010/01/16/ar-you-serious/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lighting a Sphere, part 4</title>
		<link>http://www.dafishinsea.com/blog/2009/11/29/lighting-a-sphere-part-4/</link>
		<comments>http://www.dafishinsea.com/blog/2009/11/29/lighting-a-sphere-part-4/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 04:55:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3d]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[flash]]></category>

		<guid isPermaLink="false">http://www.dafishinsea.com/blog/2009/11/29/lighting-a-sphere-part-4/</guid>
		<description><![CDATA[So last time we ended up with a chunky looking ball. Great. Lets spice things up a little by turning it into a planet, and a big one at that: Jupiter. Here is what the end result looks like:  (note &#8211; slider controls direction of lighting, in the x,y,z planes.. I apologize for the [...]]]></description>
			<content:encoded><![CDATA[<p>So last time we ended up with a chunky looking ball. Great. Lets spice things up a little by turning it into a planet, and a big one at that: Jupiter. Here is what the end result looks like:  (note &#8211; slider controls direction of lighting, in the x,y,z planes.. I apologize for the crappy GUI) </p>
<p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="800" height="600" id="planet"><param name="movie" value="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMap4.swf" /><param name="quality" value="high"/><param name="bgcolor" value="#000000"/><embed src="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMap4.swf" quality="high" bgcolor="#000000" width="800" height="600" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed></object></p>
<p> <a href="http://www.adobe.com/go/getflashplayer">flash 10 </a>required </p>
<p>If the planet is not centered, but instead you only see the bottom right part of it in the top left, refresh your browser.</p>
<p>There&#8217;s two main changes since last time. Firstly, in the pixelbender kernel I&#8217;ve applied the shading value to the color value of a second input image (called texture). Since all color values in pixel bender are between 0 and 1, simply multiplying each channel value by a constant in the same range (0-1) has the effect of lightening or darkening it, without changing the hue. First I&#8217;ll just dump out the kernel since it is not that long:</p>
<pre>
<div class="codecolorer-container glsl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br /></div></td><td><div class="glsl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000066;">&lt;</span>languageVersion <span style="color: #000066;">:</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;&gt;</span><br />
<br />
kernel NormalMap2TextureMap<br />
<span style="color: #000066;">&lt;</span> &nbsp; <span style="color: #000000; font-weight: bold;">namespace</span> <span style="color: #000066;">:</span> <span style="color: #ff0000;">&quot;com.dafishinsea&quot;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; vendor <span style="color: #000066;">:</span> <span style="color: #ff0000;">&quot;David Wilhelm&quot;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; version <span style="color: #000066;">:</span> <span style="color: #0000ff;">2</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; description <span style="color: #000066;">:</span> <span style="color: #ff0000;">&quot;kernel to apply shading to a texture map using a normal map&quot;</span><span style="color: #000066;">;</span><br />
<span style="color: #000066;">&gt;</span><br />
<span style="color: #000066;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #333399; font-weight: bold;">input</span> image4 src<span style="color: #000066;">;</span><br />
&nbsp; &nbsp; <span style="color: #333399; font-weight: bold;">input</span> image4 texture<span style="color: #000066;">;</span><br />
&nbsp; &nbsp; <span style="color: #333399; font-weight: bold;">output</span> pixel4 dst<span style="color: #000066;">;</span><br />
&nbsp; &nbsp; parameter <span style="color: #000066; font-weight: bold;">float</span> xr<br />
&nbsp; &nbsp; <span style="color: #000066;">&lt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; minValue<span style="color: #000066;">:</span> <span style="color: #000066;">-</span><span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; maxValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; defaultValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">0.1</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">&gt;;</span><br />
&nbsp; &nbsp; parameter <span style="color: #000066; font-weight: bold;">float</span> yr<br />
&nbsp; &nbsp; <span style="color: #000066;">&lt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; minValue<span style="color: #000066;">:</span> <span style="color: #000066;">-</span><span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; maxValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; defaultValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">0.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">&gt;;</span><br />
&nbsp; &nbsp; parameter <span style="color: #000066; font-weight: bold;">float</span> zr<br />
&nbsp; &nbsp; <span style="color: #000066;">&lt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; minValue<span style="color: #000066;">:</span> <span style="color: #000066;">-</span><span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; maxValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; defaultValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">0.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">&gt;;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">void</span><br />
&nbsp; &nbsp; evaluatePixel<span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//get currrent pixel color</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; pixel4 p <span style="color: #000066;">=</span> sampleNearest<span style="color: #000066;">&#40;</span>src<span style="color: #000066;">,</span>outCoord<span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; pixel4 tp <span style="color: #000066;">=</span> sampleNearest<span style="color: #000066;">&#40;</span>texture<span style="color: #000066;">,</span>outCoord<span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//image4 is a 4 element vector of RGBA channels</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//we want a vector of the first three as the normal</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> xd <span style="color: #000066;">=</span> 2<span style="color: #000066;">.</span>0<span style="color: #000066;">*</span>p<span style="color: #000066;">.</span><span style="color: #006600;">r</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> yd <span style="color: #000066;">=</span> 2<span style="color: #000066;">.</span>0<span style="color: #000066;">*</span>p<span style="color: #000066;">.</span><span style="color: #006600;">g</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> zd <span style="color: #000066;">=</span> 2<span style="color: #000066;">.</span>0<span style="color: #000066;">*</span>p<span style="color: #000066;">.</span><span style="color: #006600;">b</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; float3 normal <span style="color: #000066;">=</span> float3<span style="color: #000066;">&#40;</span>xd<span style="color: #000066;">,</span> yd<span style="color: #000066;">,</span> zd<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; normal <span style="color: #000066;">=</span> <span style="color: #993333; font-weight: bold;">normalize</span><span style="color: #000066;">&#40;</span>normal<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; float3 light <span style="color: #000066;">=</span> float3<span style="color: #000066;">&#40;</span>xr<span style="color: #000066;">,</span> yr<span style="color: #000066;">,</span> zr<span style="color: #000066;">&#41;</span> <span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; light <span style="color: #000066;">=</span> <span style="color: #993333; font-weight: bold;">normalize</span><span style="color: #000066;">&#40;</span>light<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> dotp <span style="color: #000066;">=</span> <span style="color: #993333; font-weight: bold;">dot</span><span style="color: #000066;">&#40;</span>light<span style="color: #000066;">,</span> normal<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//angle between vectors = acos (a dot b) &nbsp;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> angle <span style="color: #000066;">=</span> <span style="color: #993333; font-weight: bold;">acos</span><span style="color: #000066;">&#40;</span>dotp<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> shade <span style="color: #000066;">=</span> angle<span style="color: #000066;">/</span><span style="color: #0000ff;">3.14159265358</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//add contrast</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; shade <span style="color: #000066;">=</span> shade<span style="color: #000066;">*</span>shade<span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; dst <span style="color: #000066;">=</span> pixel4<span style="color: #000066;">&#40;</span>shade<span style="color: #000066;">*</span>tp<span style="color: #000066;">.</span><span style="color: #006600;">r</span><span style="color: #000066;">,</span> shade<span style="color: #000066;">*</span>tp<span style="color: #000066;">.</span><span style="color: #006600;">g</span><span style="color: #000066;">,</span> shade<span style="color: #000066;">*</span>tp<span style="color: #000066;">.</span><span style="color: #006600;">b</span><span style="color: #000066;">,</span> 1<span style="color: #000066;">.</span>0<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066;">&#125;</span><br />
<span style="color: #000066;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>The xr,yr,zr params are the direction of the light, which we passed in from flash. We have now added a second input image called &#8216;texture&#8217; &#8211; this is a <a href="http://maps.jpl.nasa.gov/textures/jup0vtt2.jpg">spherical map of jupiter</a>. I scaled it down a bit to 640 x 640. We grab the pixel color on line 37, just as we got the color of the normal map. Then we don&#8217;t do anything else until the end, after we have calculated the shading value. Then, instead of giving the result as the shading value, we multiply each channel of the texture by the shading value. I also fixed the glitch in the lighting by normalizing the light and normal values.</p>
<p>Now the other change is that I refactored the createNormalMap() method so that the normal map is generated on a per-pixel basis, by getting the normal of the surface of the sphere at each point (pixel) in the texture map. This results in a much smoother normal map.</p>
<pre>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/**<br />
&nbsp;* create normal map --evaluate normal for each pixel based lat/lon at that position in the sphere<br />
&nbsp;*/</span><br />
<span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> createNormalMap<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> radius:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">1</span>;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lon:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">0</span>;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lat:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">0</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> v:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>; v <span style="color: #66cc66;">&lt;</span> mapHeight; ++v<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; lat = <span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">/</span>mapHeight<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #0066CC;">PI</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> y3d:<span style="color: #0066CC;">Number</span> = radius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">cos</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> u:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>; u <span style="color: #66cc66;">&lt;</span> mapWidth; ++u<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lon = <span style="color: #66cc66;">&#40;</span>u<span style="color: #66cc66;">/</span>mapWidth<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span>TWOPI;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> x3d:<span style="color: #0066CC;">Number</span> = radius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">cos</span><span style="color: #66cc66;">&#40;</span>lon<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> z3d:<span style="color: #0066CC;">Number</span> = radius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lon<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//normal is vector from center of sphere (consider = origin) to this point</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> norm:Vector3D = <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>x3d,y3d,z3d<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; norm.<span style="color: #006600;">normalize</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> r:uint = 255<span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#40;</span>norm.<span style="color: #006600;">x</span> + 1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> g:uint = 255<span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#40;</span>norm.<span style="color: #006600;">y</span> + 1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> b:uint = 255<span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#40;</span>norm.<span style="color: #006600;">z</span> + 1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> normalColor:uint = r <span style="color: #66cc66;">&lt;&lt;</span> 16 <span style="color: #66cc66;">|</span> g <span style="color: #66cc66;">&lt;&lt;</span> 8 <span style="color: #66cc66;">|</span> b;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMap.<span style="color: #006600;">setPixel</span><span style="color: #66cc66;">&#40;</span>u,v,normalColor<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>And here is the result:</p>
<p><img src="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/normalMap.png" /></p>
<p>As you can see it is really smooth, which results in smooth lighting, even though our sphere is not a very high-polygon mesh. And I&#8217;m getting a reasonable frame rate, though using PixelBender always gets my old MacBook&#8217;s fan whirring, since it is does not have a supported graphics card, and does everything on the CPU. Even so, the performance is a good deal better than it would have been without using PixelBender. A further optimization would be to save out the normal map to a file and compile it in to the app &#8212; this would certainly be worthwile if you had a lot of 3d objects on stage. Another technique to improve performance of this sort of thing is to dynamically reduce the resolution of the texture map when the size of the projected 3d object changes. No need to process a 640 x 640 texture and normal map, if the object itself is only 100 pixels high. This is known as mipmapping, and I may well explore that later. </p>
<p>Also want to point out that this is very primitive lighting. The first time round I did this, the lighting seemed flat, so I squared the shade value to make it a bit more contrasty. A lot more can be achieved here, as lighting techniques are a whole science..some really cool things can be done. I also wanted to explore generating a rough surface texture on the sphere, but that proved more complex than I initially thought so I&#8217;ve decided to try that on a plane first. Coming up next&#8230; height maps!</p>
<h3>Da Code</h3>
<p><a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMap4.as">NormalMap4.as</a> (<a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMap4.as">GitHub</a>)</p>
<p> <a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMapShader.pbk">NormalMapShader.pbk</a> (<a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMapShader.pbk">GitHub</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dafishinsea.com/blog/2009/11/29/lighting-a-sphere-part-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lighting a Sphere part the Third &#8211; refactoring to use a normal map</title>
		<link>http://www.dafishinsea.com/blog/2009/11/22/lighting-a-sphere-part-the-third-refactoring-to-use-a-normal-map/</link>
		<comments>http://www.dafishinsea.com/blog/2009/11/22/lighting-a-sphere-part-the-third-refactoring-to-use-a-normal-map/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 04:36:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3d]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[flash]]></category>

		<guid isPermaLink="false">http://www.dafishinsea.com/blog/2009/11/22/lighting-a-sphere-part-the-third-refactoring-to-use-a-normal-map/</guid>
		<description><![CDATA[So last time we ended up with a sphere with lighting, though it was kinda chunky looking as a result of the lighting being derived from the geometry of the sphere. Now lets see if we can decouple the lighting from the geometry. Currently the lighting is done directly on the texture map based on [...]]]></description>
			<content:encoded><![CDATA[<p>So last time we ended up with a sphere with lighting, though it was kinda chunky looking as a result of the lighting being derived from the geometry of the sphere. Now lets see if we can decouple the lighting from the geometry. Currently the lighting is done directly on the texture map based on the normals of each triangle. Thus we are calculating the normals of each triangle in the mesh, and then getting the difference between the normal and the direction of the light, in order to derive the intensity of the lighting. </p>
<p>But it is not necessary to recalculate the normals every frame, since they don&#8217;t change, at least in the object coordinates. Thus it makes sense to cache the normals somehow &#8211; this is where the normal map comes in. So we can refactor our current example by converting the normals of each surface to a color, where the Red, Green, and Blue channels represent the x, y, &amp; z components of the vector. How do you transform a vector into a color? I did it like this:</p>
<pre>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> r:uint = 255<span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#40;</span>normal.<span style="color: #006600;">x</span> + 1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> g:uint = 255<span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#40;</span>normal.<span style="color: #006600;">y</span> + 1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> b:uint = 255<span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#40;</span>normal.<span style="color: #006600;">z</span> + 1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> normalColor:uint = r <span style="color: #66cc66;">&lt;&lt;</span> 16 <span style="color: #66cc66;">|</span> g <span style="color: #66cc66;">&lt;&lt;</span> 8 <span style="color: #66cc66;">|</span> b;</div></td></tr></tbody></table></div>
</pre>
<p>Since the normal is in the range of -1 to 1, we add one to it to put it in the range of 0 &#8211; 2, then divide by 2 to get it in the 0 -1 range. Multiplying by 255 gives a 8-bit value. The we shift these over to the right channels for a RGB color using binary operators. So that gives a normal map.. it actually looks quite pretty&#8230;  click the buttons in the example below to see the normal map and the texture map (which currently just has the shading in it).</p>
<p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="800" height="600" id="normalMap3"><param name="movie" value="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMap3.swf" /><param name="quality" value="high"/><param name="bgcolor" value="#FFFFFF"/><embed src="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMap3.swf" quality="high" bgcolor="#FFFFFF" width="800" height="600" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed></object></p>
<p> <a href="http://www.adobe.com/go/getflashplayer">flash 10 </a>required </p>
<p>Another advantage of having the normal map in the form of an image, is that we can use PixelBender to process it to produce the lighting/shading from the combintation of the normals and the light direction. All we have to do is the same calculations we were doing before (explained in previous lession) inside the Pixelbender kernel. As it turns out, PixelBender had lots of builtin functions to help with this kind of calculation, and it pretty straightforward. The kernel is really tiny, so here it is in full:</p>
<pre>
<div class="codecolorer-container glsl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br /></div></td><td><div class="glsl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #000066;">&lt;</span>languageVersion <span style="color: #000066;">:</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;&gt;</span><br />
<br />
&nbsp; &nbsp; kernel NormalMap2TextureMap<br />
&nbsp; &nbsp; <span style="color: #000066;">&lt;</span> &nbsp; <span style="color: #000000; font-weight: bold;">namespace</span> <span style="color: #000066;">:</span> <span style="color: #ff0000;">&quot;com.dafishinsea&quot;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; vendor <span style="color: #000066;">:</span> <span style="color: #ff0000;">&quot;David Wilhelm&quot;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; version <span style="color: #000066;">:</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; description <span style="color: #000066;">:</span> <span style="color: #ff0000;">&quot;kernel to generate a texture map (shading only) from a normal map&quot;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">&gt;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333399; font-weight: bold;">input</span> image4 src<span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333399; font-weight: bold;">output</span> pixel4 dst<span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; parameter <span style="color: #000066; font-weight: bold;">float</span> xr<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">&lt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; minValue<span style="color: #000066;">:</span> <span style="color: #000066;">-</span><span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; maxValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defaultValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">0.1</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">&gt;;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; parameter <span style="color: #000066; font-weight: bold;">float</span> yr<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">&lt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; minValue<span style="color: #000066;">:</span> <span style="color: #000066;">-</span><span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; maxValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defaultValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">0.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">&gt;;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; parameter <span style="color: #000066; font-weight: bold;">float</span> zr<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">&lt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; minValue<span style="color: #000066;">:</span> <span style="color: #000066;">-</span><span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; maxValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defaultValue<span style="color: #000066;">:</span> <span style="color: #0000ff;">0.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">&gt;;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; evaluatePixel<span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//get currrent pixel color</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pixel4 p <span style="color: #000066;">=</span> sampleNearest<span style="color: #000066;">&#40;</span>src<span style="color: #000066;">,</span>outCoord<span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//image4 is a 4 element vector of RGBA channels</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//we want a vector of the first three as the normal</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> xd <span style="color: #000066;">=</span> 2<span style="color: #000066;">.</span>0<span style="color: #000066;">*</span>p<span style="color: #000066;">.</span><span style="color: #006600;">r</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> yd <span style="color: #000066;">=</span> 2<span style="color: #000066;">.</span>0<span style="color: #000066;">*</span>p<span style="color: #000066;">.</span><span style="color: #006600;">g</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> zd <span style="color: #000066;">=</span> 2<span style="color: #000066;">.</span>0<span style="color: #000066;">*</span>p<span style="color: #000066;">.</span><span style="color: #006600;">b</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">1.0</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float3 normal <span style="color: #000066;">=</span> float3<span style="color: #000066;">&#40;</span>xd<span style="color: #000066;">,</span> yd<span style="color: #000066;">,</span> zd<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float3 light <span style="color: #000066;">=</span> float3<span style="color: #000066;">&#40;</span>xr<span style="color: #000066;">,</span> yr<span style="color: #000066;">,</span> zr<span style="color: #000066;">&#41;</span> <span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> dotp <span style="color: #000066;">=</span> <span style="color: #993333; font-weight: bold;">dot</span><span style="color: #000066;">&#40;</span>light<span style="color: #000066;">,</span> normal<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//angle between vectors = acos (a dot b) &nbsp;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> angle <span style="color: #000066;">=</span> <span style="color: #993333; font-weight: bold;">acos</span><span style="color: #000066;">&#40;</span>dotp<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">float</span> clr <span style="color: #000066;">=</span> angle<span style="color: #000066;">/</span><span style="color: #0000ff;">3.14159265358</span><span style="color: #000066;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dst <span style="color: #000066;">=</span> pixel4<span style="color: #000066;">&#40;</span>clr<span style="color: #000066;">,</span> clr<span style="color: #000066;">,</span> clr<span style="color: #000066;">,</span> 1<span style="color: #000066;">.</span>0<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>All this does is convert the normal (color at the source pixel) to a shading color (greyscale) depending on its variance with the lighting direction (which is passed in to the kernel as a parameter &#8212; actually 3, for x,y,z components). The huge advantage here is that this process gets called by Actionscript as a ShaderJob, and it runs ansynchronously. The result gets used as the texture for the sphere. I won&#8217;t go over the mechanics of using a ShaderJob &#8212; check out <a href="http://www.flashmagazine.com/tutorials/detail/using_pixel_bender_to_calculate_information/#When:16:28:29Z">this article</a> for more info. Or you can just read the code below, for all the gory details.</p>
<pre>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br />216<br />217<br />218<br />219<br />220<br />221<br />222<br />223<br />224<br />225<br />226<br />227<br />228<br />229<br />230<br />231<br />232<br />233<br />234<br />235<br />236<br />237<br />238<br />239<br />240<br />241<br />242<br />243<br />244<br />245<br />246<br />247<br />248<br />249<br />250<br />251<br />252<br />253<br />254<br />255<br />256<br />257<br />258<br />259<br />260<br />261<br />262<br />263<br />264<br />265<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; package com.<span style="color: #006600;">dafishinsea</span>.<span style="color: #006600;">tutorials</span>.<span style="color: #006600;">normalmap</span> <span style="color: #66cc66;">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> com.<span style="color: #006600;">bit101</span>.<span style="color: #006600;">components</span>.<span style="color: #66cc66;">*</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">Bitmap</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">BitmapData</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">Shader</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">ShaderJob</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">Shape</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">Sprite</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">StageAlign</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">StageScaleMode</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">TriangleCulling</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">events</span>.<span style="color: #006600;">Event</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">filters</span>.<span style="color: #006600;">ShaderFilter</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Matrix3D</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">PerspectiveProjection</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Point</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Rectangle</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Utils3D</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Vector3D</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">utils</span>.<span style="color: #006600;">ByteArray</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">import</span> net.<span style="color: #006600;">hires</span>.<span style="color: #006600;">debug</span>.<span style="color: #006600;">Stats</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>SWF<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">backgroundColor</span>=<span style="color: #ff0000;">&quot;0xffffff&quot;</span>, <span style="color: #0066CC;">width</span>=<span style="color: #ff0000;">&quot;800&quot;</span>, <span style="color: #0066CC;">height</span>=<span style="color: #ff0000;">&quot;600&quot;</span>, frameRate=<span style="color: #ff0000;">&quot;50&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>&nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> NormalMap3 <span style="color: #0066CC;">extends</span> Sprite <span style="color: #66cc66;">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> texture:BitmapData = <span style="color: #000000; font-weight: bold;">new</span> BitmapData<span style="color: #66cc66;">&#40;</span>500,500,<span style="color: #000000; font-weight: bold;">false</span>,0xFFFFFF<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> textureBmp:Bitmap = <span style="color: #000000; font-weight: bold;">new</span> Bitmap<span style="color: #66cc66;">&#40;</span>texture<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> normalMap:BitmapData = <span style="color: #000000; font-weight: bold;">new</span> BitmapData<span style="color: #66cc66;">&#40;</span>500,500,<span style="color: #000000; font-weight: bold;">false</span>,0xFFFFFF<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> normalBmp:Bitmap = <span style="color: #000000; font-weight: bold;">new</span> Bitmap<span style="color: #66cc66;">&#40;</span>normalMap<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> normalMapShp:Shape = <span style="color: #000000; font-weight: bold;">new</span> Shape<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> vertices:Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> indices:Vector.<span style="color: #66cc66;">&lt;</span>int<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> uvtData:Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> perspective: PerspectiveProjection;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> projectionMatrix : Matrix3D;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> rotationMatrix : Matrix3D;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> projectedVerts:Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> focalLength:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">50</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> container:Sprite;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> const <span style="color: #0066CC;">PI</span>:<span style="color: #0066CC;">Number</span> = <span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">PI</span>;<span style="color: #808080; font-style: italic;">//half revolution in radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> const HALFPI:<span style="color: #0066CC;">Number</span> = <span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">PI</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<span style="color: #808080; font-style: italic;">//1/4 revolution in radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> const TWOPI:<span style="color: #0066CC;">Number</span> = 2<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">PI</span>;<span style="color: #808080; font-style: italic;">//full revolution in radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//x,yz rotation</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> rx:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">60</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> ry:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">40</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> rz:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">30</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> testBmp:Bitmap;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> r:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">0</span>;<span style="color: #808080; font-style: italic;">//yrotation of sphere</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> normalMapShader:Shader;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> shaderJob:ShaderJob;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> input:ByteArray;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> output:ByteArray;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> normalMapRdo:PushButton;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> textureMapRdo:PushButton;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> noMapsRdo:PushButton;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>Embed<span style="color: #66cc66;">&#40;</span>source=<span style="color: #ff0000;">&quot;NormalMapShader.pbj&quot;</span>, mimeType=<span style="color: #ff0000;">&quot;application/octet-stream&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> NormalMapShader:<span style="color: #000000; font-weight: bold;">Class</span>; <br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> NormalMap3<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">trace</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;init&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> init<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">stage</span>.<span style="color: #0066CC;">align</span> = StageAlign.<span style="color: #006600;">TOP_LEFT</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">stage</span>.<span style="color: #0066CC;">scaleMode</span> = StageScaleMode.<span style="color: #006600;">NO_SCALE</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indices = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>int<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uvtData = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//set up perspective</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; perspective = <span style="color: #000000; font-weight: bold;">new</span> PerspectiveProjection<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; perspective.<span style="color: #006600;">fieldOfView</span> = <span style="color: #cc66cc;">50</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//3D transformation matrix - used to rotate object</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectionMatrix = perspective.<span style="color: #006600;">toMatrix3D</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rotationMatrix = <span style="color: #000000; font-weight: bold;">new</span> Matrix3D<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<span style="color: #808080; font-style: italic;">//used to keep track of rotation of the sphere</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectedVerts &nbsp; = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//container &nbsp;to hold scene</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container = <span style="color: #000000; font-weight: bold;">new</span> Sprite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">x</span> = <span style="color: #0066CC;">stage</span>.<span style="color: #006600;">stageWidth</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">y</span> = <span style="color: #0066CC;">stage</span>.<span style="color: #006600;">stageHeight</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addChild<span style="color: #66cc66;">&#40;</span>container<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; createSphere<span style="color: #66cc66;">&#40;</span>100, 40, 80<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; createNormalMap<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; createShaderJob<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addEventListener<span style="color: #66cc66;">&#40;</span>Event.<span style="color: #006600;">ENTER_FRAME</span>, <span style="color: #0066CC;">onEnterFrame</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addEventListener<span style="color: #66cc66;">&#40;</span>Event.<span style="color: #006600;">RENDER</span>, render, <span style="color: #000000; font-weight: bold;">false</span>, 0, <span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addChild<span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Stats<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//texture map</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//controls</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapRdo = <span style="color: #000000; font-weight: bold;">new</span> PushButton<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">this</span>, <span style="color: #cc66cc;">500</span>, <span style="color: #cc66cc;">30</span>, <span style="color: #ff0000;">&quot;Show normal map&quot;</span>, onNomalMapBtnClick<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; textureMapRdo = <span style="color: #000000; font-weight: bold;">new</span> PushButton<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">this</span>, <span style="color: #cc66cc;">500</span>, <span style="color: #cc66cc;">50</span>, <span style="color: #ff0000;">&quot;Show texture map&quot;</span>, onTextureRdoClick<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; noMapsRdo = <span style="color: #000000; font-weight: bold;">new</span> PushButton<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">this</span>, <span style="color: #cc66cc;">500</span>, <span style="color: #cc66cc;">10</span>, <span style="color: #ff0000;">&quot;Show only sphere&quot;</span>, onNoMapsRdoClick<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; protected <span style="color: #000000; font-weight: bold;">function</span> onNomalMapBtnClick<span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>textureBmp.<span style="color: #006600;">parent</span> == <span style="color: #0066CC;">this</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; removeChild<span style="color: #66cc66;">&#40;</span>textureBmp<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addChild<span style="color: #66cc66;">&#40;</span>normalBmp<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; protected <span style="color: #000000; font-weight: bold;">function</span> onTextureRdoClick<span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>normalBmp.<span style="color: #006600;">parent</span> == <span style="color: #0066CC;">this</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; removeChild<span style="color: #66cc66;">&#40;</span>normalBmp<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addChild<span style="color: #66cc66;">&#40;</span>textureBmp<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; protected <span style="color: #000000; font-weight: bold;">function</span> onNoMapsRdoClick<span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>normalBmp.<span style="color: #006600;">parent</span> == <span style="color: #0066CC;">this</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; removeChild<span style="color: #66cc66;">&#40;</span>normalBmp<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>textureBmp.<span style="color: #006600;">parent</span> == <span style="color: #0066CC;">this</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; removeChild<span style="color: #66cc66;">&#40;</span>textureBmp<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> createSphere<span style="color: #66cc66;">&#40;</span>radius:<span style="color: #0066CC;">Number</span>, rows:<span style="color: #0066CC;">int</span>, cols:<span style="color: #0066CC;">int</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lon_incr:<span style="color: #0066CC;">Number</span> = TWOPI<span style="color: #66cc66;">/</span>cols;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lat_incr = <span style="color: #0066CC;">PI</span><span style="color: #66cc66;">/</span>rows;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lon:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">0</span>;<span style="color: #808080; font-style: italic;">//angle of rotation around the y axis, *in radians*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lat:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">0</span>;<span style="color: #808080; font-style: italic;">//angle of rotation around the x axis</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> x:<span style="color: #0066CC;">Number</span>, y:<span style="color: #0066CC;">Number</span>, z:<span style="color: #0066CC;">Number</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> vnum:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> ind:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//a full rotation is PI radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> h:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>; h <span style="color: #66cc66;">&lt;</span>= rows; ++h<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lon = <span style="color: #cc66cc;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y = radius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">cos</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<span style="color: #808080; font-style: italic;">//need to shift angle downwards by 1/4 rev</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> v:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>; v <span style="color: #66cc66;">&lt;</span>= cols; ++v<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x = radius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">cos</span><span style="color: #66cc66;">&#40;</span>lon<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; z = radius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lon<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<span style="color: #808080; font-style: italic;">//seen from above, z = y</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//add vertex triplet</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>vnum<span style="color: #66cc66;">&#93;</span> = x;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>vnum+1<span style="color: #66cc66;">&#93;</span> = y;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>vnum+2<span style="color: #66cc66;">&#93;</span> = z;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//uvts</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uvtData<span style="color: #66cc66;">&#91;</span>vnum<span style="color: #66cc66;">&#93;</span> = v<span style="color: #66cc66;">/</span>cols;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uvtData<span style="color: #66cc66;">&#91;</span>vnum+1<span style="color: #66cc66;">&#93;</span> &nbsp;= h<span style="color: #66cc66;">/</span>rows;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uvtData<span style="color: #66cc66;">&#91;</span>vnum+2<span style="color: #66cc66;">&#93;</span> = <span style="color: #cc66cc;">1</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vnum+=<span style="color: #cc66cc;">3</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//add indices</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>h <span style="color: #66cc66;">&lt;</span> rows <span style="color: #66cc66;">&amp;&amp;</span> v <span style="color: #66cc66;">&lt;</span> cols<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indices.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span>ind, ind+1, ind + cols+1<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indices.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span>ind + cols+1, ind+1, ind + cols + 2<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ind+=<span style="color: #cc66cc;">1</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lon += lon_incr;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lat += lat_incr;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* create ShaderJob for use later<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> createShaderJob<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShader = <span style="color: #000000; font-weight: bold;">new</span> Shader<span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> NormalMapShader<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShader.<span style="color: #0066CC;">data</span>.<span style="color: #006600;">src</span>.<span style="color: #0066CC;">width</span> = normalMap.<span style="color: #0066CC;">width</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShader.<span style="color: #0066CC;">data</span>.<span style="color: #006600;">src</span>.<span style="color: #0066CC;">height</span> = normalMap.<span style="color: #0066CC;">height</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShader.<span style="color: #0066CC;">data</span>.<span style="color: #006600;">src</span>.<span style="color: #006600;">input</span> = normalMap; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shaderJob = <span style="color: #000000; font-weight: bold;">new</span> ShaderJob<span style="color: #66cc66;">&#40;</span>normalMapShader, texture, <span style="color: #0066CC;">width</span>, <span style="color: #0066CC;">height</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shaderJob.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>Event.<span style="color: #006600;">COMPLETE</span>, shaderJobCompleteHandler<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shaderJob.<span style="color: #0066CC;">start</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* shade job complete<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> shaderJobCompleteHandler<span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//update params and restart job</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lightDir:Vector3D = rotationMatrix.<span style="color: #006600;">transformVector</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>1,1,1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lightDir.<span style="color: #006600;">normalize</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShader.<span style="color: #0066CC;">data</span>.<span style="color: #006600;">xr</span>.<span style="color: #006600;">value</span> = <span style="color: #66cc66;">&#91;</span>lightDir.<span style="color: #006600;">x</span><span style="color: #66cc66;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShader.<span style="color: #0066CC;">data</span>.<span style="color: #006600;">yr</span>.<span style="color: #006600;">value</span> = <span style="color: #66cc66;">&#91;</span>lightDir.<span style="color: #006600;">y</span><span style="color: #66cc66;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShader.<span style="color: #0066CC;">data</span>.<span style="color: #006600;">zr</span>.<span style="color: #006600;">value</span> = <span style="color: #66cc66;">&#91;</span>lightDir.<span style="color: #006600;">z</span><span style="color: #66cc66;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shaderJob = <span style="color: #000000; font-weight: bold;">new</span> ShaderJob<span style="color: #66cc66;">&#40;</span>normalMapShader, texture, <span style="color: #0066CC;">width</span>, <span style="color: #0066CC;">height</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shaderJob.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>Event.<span style="color: #006600;">COMPLETE</span>, shaderJobCompleteHandler<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shaderJob.<span style="color: #0066CC;">start</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* create normal map from geometry to reuse for lighting<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> createNormalMap<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> i:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>; i <span style="color: #66cc66;">&lt;</span> indices.<span style="color: #0066CC;">length</span>; i+=<span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//get the 3 points of the triangle as Vector3D objects</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> pt1:Vector3D = <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> pt2:Vector3D = <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> pt3:Vector3D = <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//subtract the first two from the third</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> d1:Vector3D = pt3.<span style="color: #006600;">subtract</span><span style="color: #66cc66;">&#40;</span>pt1<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> d2:Vector3D = pt3.<span style="color: #006600;">subtract</span><span style="color: #66cc66;">&#40;</span>pt2<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//get the cross-product of the results to get the normal</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> normal:Vector3D = d1.<span style="color: #006600;">crossProduct</span><span style="color: #66cc66;">&#40;</span>d2<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normal.<span style="color: #006600;">normalize</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> r:uint = 255<span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#40;</span>normal.<span style="color: #006600;">x</span> + 1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> g:uint = 255<span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#40;</span>normal.<span style="color: #006600;">y</span> + 1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> b:uint = 255<span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#40;</span>normal.<span style="color: #006600;">z</span> + 1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> normalColor:uint = r <span style="color: #66cc66;">&lt;&lt;</span> 16 <span style="color: #66cc66;">|</span> g <span style="color: #66cc66;">&lt;&lt;</span> 8 <span style="color: #66cc66;">|</span> b;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShp.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>normalColor<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> p1:Point = <span style="color: #000000; font-weight: bold;">new</span> Point<span style="color: #66cc66;">&#40;</span>uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>normalMap.<span style="color: #0066CC;">width</span>, uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>normalMap.<span style="color: #0066CC;">height</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> p2:Point = <span style="color: #000000; font-weight: bold;">new</span> Point<span style="color: #66cc66;">&#40;</span>uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>normalMap.<span style="color: #0066CC;">width</span>, uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>normalMap.<span style="color: #0066CC;">height</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> p3:Point = <span style="color: #000000; font-weight: bold;">new</span> Point<span style="color: #66cc66;">&#40;</span>uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>normalMap.<span style="color: #0066CC;">width</span>, uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>normalMap.<span style="color: #0066CC;">height</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShp.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">moveTo</span><span style="color: #66cc66;">&#40;</span>p1.<span style="color: #006600;">x</span>, p1.<span style="color: #006600;">y</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShp.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">lineTo</span><span style="color: #66cc66;">&#40;</span>p2.<span style="color: #006600;">x</span>, p2.<span style="color: #006600;">y</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShp.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">lineTo</span><span style="color: #66cc66;">&#40;</span>p3.<span style="color: #006600;">x</span>, p3.<span style="color: #006600;">y</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShp.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">lineTo</span><span style="color: #66cc66;">&#40;</span>p1.<span style="color: #006600;">x</span>, p1.<span style="color: #006600;">y</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMapShp.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normalMap.<span style="color: #006600;">draw</span><span style="color: #66cc66;">&#40;</span>normalMapShp<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* save the normal map -- so I can play with it in PixelBender Toolkit ;)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> onSaveBtnClick<span style="color: #66cc66;">&#40;</span>click:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> savingBmp:SavingBitmap = <span style="color: #000000; font-weight: bold;">new</span> SavingBitmap<span style="color: #66cc66;">&#40;</span>normalMap<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; savingBmp.<span style="color: #006600;">encoderType</span> = <span style="color: #ff0000;">&quot;png&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; savingBmp.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;normalMap.png&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">onEnterFrame</span><span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//createSphere()</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; update<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> update<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r+=<span style="color: #cc66cc;">0.5</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rotationMatrix = <span style="color: #000000; font-weight: bold;">new</span> Matrix3D<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rotationMatrix.<span style="color: #006600;">prependRotation</span><span style="color: #66cc66;">&#40;</span>-r, <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>0,1,0<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectionMatrix = perspective.<span style="color: #006600;">toMatrix3D</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectionMatrix.<span style="color: #006600;">prependTranslation</span><span style="color: #66cc66;">&#40;</span>0.0,0.0,250<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectionMatrix.<span style="color: #006600;">prependRotation</span><span style="color: #66cc66;">&#40;</span>r, <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>0,1,0<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">stage</span>.<span style="color: #006600;">invalidate</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<span style="color: #808080; font-style: italic;">//trigger render event</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> render<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">e</span>:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">clear</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Utils3D.<span style="color: #006600;">projectVectors</span><span style="color: #66cc66;">&#40;</span>projectionMatrix, vertices, projectedVerts, uvtData<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">beginBitmapFill</span><span style="color: #66cc66;">&#40;</span>texture,<span style="color: #000000; font-weight: bold;">null</span>, <span style="color: #000000; font-weight: bold;">false</span>, <span style="color: #000000; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawTriangles</span><span style="color: #66cc66;">&#40;</span>projectedVerts, indices, uvtData, TriangleCulling.<span style="color: #006600;">POSITIVE</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>You may have noticed that there is a white blotch in the darkest part of the shadow&#8230; this is a bug in the shader, which I have yet to figure out&#8230; let me know if you know what it is <img src='http://www.dafishinsea.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The next step is to liberate the normal map from the actual geometry, in order to make the lighting more detailed than the geometry&#8230; the dramatic conclusion to this series is coming soon! </p>
<p>As usual, code is on GitHub&#8230;</p>
<p><a href="http://github.com/bigfish/fishpond/blob/master/src/com/dafishinsea/tutorials/normalmap/NormalMap3.as">NormalMap3.as</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dafishinsea.com/blog/2009/11/22/lighting-a-sphere-part-the-third-refactoring-to-use-a-normal-map/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lighting a 3D object in Flash, pt 2</title>
		<link>http://www.dafishinsea.com/blog/2009/11/14/lighting-a-3d-object-in-flash-pt-2/</link>
		<comments>http://www.dafishinsea.com/blog/2009/11/14/lighting-a-3d-object-in-flash-pt-2/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 03:51:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3d]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[flash]]></category>

		<guid isPermaLink="false">http://www.dafishinsea.com/blog/2009/11/14/lighting-a-3d-object-in-flash-pt-2/</guid>
		<description><![CDATA[OK, so we have a sphere, now how about some lighting&#8230; Basically what we need to do is determine the angle of each surface  (the normal) and then the difference between that angle and the angle of light. The greater the difference, the brighter the surface should be. If this doesn&#8217;t make sense then [...]]]></description>
			<content:encoded><![CDATA[<p>OK, so we have a sphere, now how about some lighting&#8230; Basically what we need to do is determine the angle of each surface  (the normal) and then the difference between that angle and the angle of light. The greater the difference, the brighter the surface should be. If this doesn&#8217;t make sense then think of how a surface whose normal was the same as the angle of the light would be pointing away from the light, and should be totally dark.</p>
<p>A while back I came up with a solution for lighting a mesh object using the Flash 10 3D APIs. This was my own idea based on the knowledge that the normal of a triangle can be computed by getting a vector which is perpendicular to two of its sides. The following crude diagram may help.. the triangle is ABC, the normal is AN. The normal is considered to be facing away from the surface. You&#8217;ll need to imagine that ABC is not flat on the picture plane, with B pointing away from you, and with NA perpendicular to AC and AB, which it doesn&#8217;t really look like it is in the picture, but theres only so much you can do with ASCII art :p </p>
<pre>
   N
    \        B
     \      /|
      \    / |
       \  /  |
        \/___|
         A    C
</pre>
<p>So the plan then is to iterate over every triangle in the sphere, and determine its normal, and then the luminosity of that surface by getting the difference between it and the light. The math for this involves vectors, and was new stuff for me. I recommend the excellent book &#8216;3D Math Primer for Graphics and Game Development&#8217;, but any introductory text to 3D graphics should be helpful to grok these concepts. Fortunately the Vector3D class has some handy methods to do such calculations, and you just need to know which method to call. </p>
<p>To get the normal of a triangle you need to convert the points to vectors, and then get the cross-product between two of these vectors.I just created 3 Vector3D objects for each point and subtracted them from each other to get the vectors representing the sides of the triangle. Eg. subtracting point A from B in the above triangle, gives you the vector representing AB. Note that you need to use the Vector3D subtract() method, not regular &#8216;-&#8217; since the vector subtract() subtracts each component of the vector for you. At this point the code may help clarify (I will give complete code later) : </p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//pt1,2,3 are Vector3D objects representing points of a triangle</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> d1:Vector3D = pt3.<span style="color: #006600;">subtract</span><span style="color: #66cc66;">&#40;</span>pt1<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> d2:Vector3D = pt3.<span style="color: #006600;">subtract</span><span style="color: #66cc66;">&#40;</span>pt2<span style="color: #66cc66;">&#41;</span>;</div></td></tr></tbody></table></div>
<p>Then the final step to get the normal of the triangle surface is to get the cross-product of the two vectors we just derived.</p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//get the cross-product of the results to get the normal</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> normal:Vector3D = d1.<span style="color: #006600;">crossProduct</span><span style="color: #66cc66;">&#40;</span>d2<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; normal.<span style="color: #006600;">normalize</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></td></tr></tbody></table></div>
<p>The normalize() method just makes sure the length of the vector is between -1 &amp; 1. Now to get the difference between the surface normal and the light vector, we can use the angleBetween() method.</p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> angleDiff:<span style="color: #0066CC;">Number</span> = Vector3D.<span style="color: #006600;">angleBetween</span><span style="color: #66cc66;">&#40;</span>lightDir,normal<span style="color: #66cc66;">&#41;</span>;</div></td></tr></tbody></table></div>
<p>Then I converted the this difference to a color, and draw it onto the bitmapData being used as the texture of the object. I just used the drawing API to draw each triangle on a Sprite, then drew the sprite onto the bitmapData being used in the beginFill()  method just before the call to drawTriangles() in the render method. </p>
<p>When I first did this I found that when I rotated the sphere, the lighting was rotating along with it. So I had to transform the light vector using the Matrix3D which I was using to rotate the sphere. This did not work as expected. Then I realized I had to transform the light vector using a Matrix3D which was the inverse of the rotation of the sphere (the projection matrix). So I thought I could just call the invert() method on the projection matrix and use that to transform the light. But it turns out that the projection matrix, which is derived from a perspective projection, is not invertible. SO&#8230; I had to make another Matrix3D, and rotate it in the opposite direction, in order to use it for correcting the light direction. </p>
<p>Here&#8217;s the working example, followed by the code. There&#8217;s a lot of it, but that will improve soon&#8230; see comments after code.</p>
<p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="800" height="600" id="shadedSphere"><param name="movie" value="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMap2.swf" /><param name="quality" value="high"/><param name="bgcolor" value="0x000000"/><embed src="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMap2.swf" quality="high" bgcolor="0x000000" width="800" height="600" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed></object></p>
<p> <a href="http://www.adobe.com/go/getflashplayer">flash 10 </a>required </p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">package com.<span style="color: #006600;">dafishinsea</span>.<span style="color: #006600;">tutorials</span>.<span style="color: #006600;">normalmap</span> <span style="color: #66cc66;">&#123;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">Bitmap</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">BitmapData</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">Shape</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">Sprite</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">StageAlign</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">StageScaleMode</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">TriangleCulling</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">events</span>.<span style="color: #006600;">Event</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Matrix3D</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">PerspectiveProjection</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Point</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Rectangle</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Utils3D</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Vector3D</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> net.<span style="color: #006600;">hires</span>.<span style="color: #006600;">debug</span>.<span style="color: #006600;">Stats</span>;<br />
<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>SWF<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">backgroundColor</span>=<span style="color: #ff0000;">&quot;0xffffff&quot;</span>, <span style="color: #0066CC;">width</span>=<span style="color: #ff0000;">&quot;800&quot;</span>, <span style="color: #0066CC;">height</span>=<span style="color: #ff0000;">&quot;600&quot;</span>, frameRate=<span style="color: #ff0000;">&quot;30&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> NormalMap2 <span style="color: #0066CC;">extends</span> Sprite <span style="color: #66cc66;">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> texture:BitmapData = <span style="color: #000000; font-weight: bold;">new</span> BitmapData<span style="color: #66cc66;">&#40;</span>500,500,<span style="color: #000000; font-weight: bold;">false</span>,0xFF0000<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> vertices:Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> indices:Vector.<span style="color: #66cc66;">&lt;</span>int<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> uvtData:Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> perspective: PerspectiveProjection;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> projectionMatrix : Matrix3D;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> rotationMatrix : Matrix3D;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> projectedVerts:Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> focalLength:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">50</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> container:Sprite;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> const <span style="color: #0066CC;">PI</span>:<span style="color: #0066CC;">Number</span> = <span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">PI</span>;<span style="color: #808080; font-style: italic;">//half revolution in radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> const HALFPI:<span style="color: #0066CC;">Number</span> = <span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">PI</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<span style="color: #808080; font-style: italic;">//1/4 revolution in radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> const TWOPI:<span style="color: #0066CC;">Number</span> = 2<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">PI</span>;<span style="color: #808080; font-style: italic;">//full revolution in radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//x,yz rotation</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> rx:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">60</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> ry:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">40</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> rz:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">30</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> testBmp:Bitmap;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> r:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">0</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> NormalMap2<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> init<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">stage</span>.<span style="color: #0066CC;">align</span> = StageAlign.<span style="color: #006600;">TOP_LEFT</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">stage</span>.<span style="color: #0066CC;">scaleMode</span> = StageScaleMode.<span style="color: #006600;">NO_SCALE</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indices = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>int<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uvtData = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//set up perspective</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; perspective = <span style="color: #000000; font-weight: bold;">new</span> PerspectiveProjection<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; perspective.<span style="color: #006600;">fieldOfView</span> = <span style="color: #cc66cc;">50</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//3D transformation matrix - used to rotate object</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectionMatrix = perspective.<span style="color: #006600;">toMatrix3D</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rotationMatrix = <span style="color: #000000; font-weight: bold;">new</span> Matrix3D<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<span style="color: #808080; font-style: italic;">//used to keep track of rotation of the sphere</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//using separate one since Matrix3D derived from perspectiveProjection is not invertible</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectedVerts &nbsp; = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//container &nbsp;to hold scene</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container = <span style="color: #000000; font-weight: bold;">new</span> Sprite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">x</span> = <span style="color: #0066CC;">stage</span>.<span style="color: #006600;">stageWidth</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">y</span> = <span style="color: #0066CC;">stage</span>.<span style="color: #006600;">stageHeight</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addChild<span style="color: #66cc66;">&#40;</span>container<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//add test bitmap</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//testBmp = new Bitmap(texture);</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//container.addChild(testBmp);</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; createSphere<span style="color: #66cc66;">&#40;</span>100, 20, 40<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addEventListener<span style="color: #66cc66;">&#40;</span>Event.<span style="color: #006600;">ENTER_FRAME</span>, <span style="color: #0066CC;">onEnterFrame</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//update();</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//render();</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addChild<span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Stats<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> createSphere<span style="color: #66cc66;">&#40;</span>radius:<span style="color: #0066CC;">Number</span>, rows:<span style="color: #0066CC;">int</span>, cols:<span style="color: #0066CC;">int</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lon_incr:<span style="color: #0066CC;">Number</span> = TWOPI<span style="color: #66cc66;">/</span>cols;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lat_incr = <span style="color: #0066CC;">PI</span><span style="color: #66cc66;">/</span>rows;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lon:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">0</span>;<span style="color: #808080; font-style: italic;">//angle of rotation around the y axis, *in radians*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lat:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">0</span>;<span style="color: #808080; font-style: italic;">//angle of rotation around the x axis</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> x:<span style="color: #0066CC;">Number</span>, y:<span style="color: #0066CC;">Number</span>, z:<span style="color: #0066CC;">Number</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> vnum:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> ind:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//a full rotation is PI radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> h:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>; h <span style="color: #66cc66;">&lt;</span>= rows; ++h<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y = radius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">cos</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<span style="color: #808080; font-style: italic;">//need to shift angle downwards by 1/4 rev</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> v:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>; v <span style="color: #66cc66;">&lt;</span>= cols; ++v<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x = radius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">cos</span><span style="color: #66cc66;">&#40;</span>lon<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; z = radius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lon<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<span style="color: #808080; font-style: italic;">//seen from above, z = y</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//add vertex triplet</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>vnum<span style="color: #66cc66;">&#93;</span> = x;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>vnum+1<span style="color: #66cc66;">&#93;</span> = y;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>vnum+2<span style="color: #66cc66;">&#93;</span> = z;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//uvts</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uvtData<span style="color: #66cc66;">&#91;</span>vnum<span style="color: #66cc66;">&#93;</span> = v<span style="color: #66cc66;">/</span>cols;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uvtData<span style="color: #66cc66;">&#91;</span>vnum+1<span style="color: #66cc66;">&#93;</span> &nbsp;= h<span style="color: #66cc66;">/</span>rows;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uvtData<span style="color: #66cc66;">&#91;</span>vnum+2<span style="color: #66cc66;">&#93;</span> = <span style="color: #cc66cc;">1</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vnum+=<span style="color: #cc66cc;">3</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//add indices</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>h <span style="color: #66cc66;">&lt;</span> rows <span style="color: #66cc66;">&amp;&amp;</span> v <span style="color: #66cc66;">&lt;</span> cols<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indices.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span>ind, ind+1, ind + cols+1<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indices.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span>ind + cols+1, ind+1, ind + cols + 2<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ind+=<span style="color: #cc66cc;">1</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lon += lon_incr;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lat += lat_incr;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">onEnterFrame</span><span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//createSphere(100, 20, 40);</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; update<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; render<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> update<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r+=<span style="color: #cc66cc;">0.5</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rotationMatrix = <span style="color: #000000; font-weight: bold;">new</span> Matrix3D<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectionMatrix.<span style="color: #006600;">prependTranslation</span><span style="color: #66cc66;">&#40;</span>0.0,0.0,250<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rotationMatrix.<span style="color: #006600;">prependRotation</span><span style="color: #66cc66;">&#40;</span>-r, <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//container.x = stage.stageWidth/2 ;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//container.y = stage.stageHeight/2 ;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectionMatrix = perspective.<span style="color: #006600;">toMatrix3D</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectionMatrix.<span style="color: #006600;">prependTranslation</span><span style="color: #66cc66;">&#40;</span>0.0,0.0,250<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectionMatrix.<span style="color: #006600;">prependRotation</span><span style="color: #66cc66;">&#40;</span>r, <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>0,1,0<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> render<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//update texture map based on triangle normals</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> tr:Shape = <span style="color: #000000; font-weight: bold;">new</span> Shape<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//for(var i:int = 0; i &lt; indices.length; i+=3){</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> i:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>; i <span style="color: #66cc66;">&lt;</span> indices.<span style="color: #0066CC;">length</span>; i+=<span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//get the 3 points of the triangle as Vector3D objects</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> pt1:Vector3D = <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> pt2:Vector3D = <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> pt3:Vector3D = <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//subtract the first two from the third</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> d1:Vector3D = pt3.<span style="color: #006600;">subtract</span><span style="color: #66cc66;">&#40;</span>pt1<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> d2:Vector3D = pt3.<span style="color: #006600;">subtract</span><span style="color: #66cc66;">&#40;</span>pt2<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//get the cross-product of the results to get the normal</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> normal:Vector3D = d1.<span style="color: #006600;">crossProduct</span><span style="color: #66cc66;">&#40;</span>d2<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; normal.<span style="color: #006600;">normalize</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//get the angle between the normal and the lighting angle</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lightDir:Vector3D = rotationMatrix.<span style="color: #006600;">transformVector</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>1000,1000,1000<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//TODOtransform the light dir by the sphere matrix</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> angleDiff:<span style="color: #0066CC;">Number</span> = Vector3D.<span style="color: #006600;">angleBetween</span><span style="color: #66cc66;">&#40;</span>lightDir,normal<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//trace(&quot;angleDiff:&quot;+angleDiff);</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//normalize shade to 0-1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> r:<span style="color: #0066CC;">int</span> = <span style="color: #0066CC;">isNaN</span><span style="color: #66cc66;">&#40;</span>angleDiff<span style="color: #66cc66;">&#41;</span>?255:255<span style="color: #66cc66;">*</span>angleDiff<span style="color: #66cc66;">/</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">PI</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> shadow:uint &nbsp;= &nbsp;r <span style="color: #66cc66;">&lt;&lt;</span> 16 <span style="color: #66cc66;">|</span> r <span style="color: #66cc66;">&lt;&lt;</span> 8 <span style="color: #66cc66;">|</span> r;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//draw shaded texture</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tr.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>shadow<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> p1:Point = <span style="color: #000000; font-weight: bold;">new</span> Point<span style="color: #66cc66;">&#40;</span>uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>texture.<span style="color: #0066CC;">width</span>, uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>texture.<span style="color: #0066CC;">height</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> p2:Point = <span style="color: #000000; font-weight: bold;">new</span> Point<span style="color: #66cc66;">&#40;</span>uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>texture.<span style="color: #0066CC;">width</span>, uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>texture.<span style="color: #0066CC;">height</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> p3:Point = <span style="color: #000000; font-weight: bold;">new</span> Point<span style="color: #66cc66;">&#40;</span>uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>texture.<span style="color: #0066CC;">width</span>, uvtData<span style="color: #66cc66;">&#91;</span>indices<span style="color: #66cc66;">&#91;</span>i+2<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>3+1<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">*</span>texture.<span style="color: #0066CC;">height</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tr.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">moveTo</span><span style="color: #66cc66;">&#40;</span>p1.<span style="color: #006600;">x</span>, p1.<span style="color: #006600;">y</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tr.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">lineTo</span><span style="color: #66cc66;">&#40;</span>p2.<span style="color: #006600;">x</span>, p2.<span style="color: #006600;">y</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tr.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">lineTo</span><span style="color: #66cc66;">&#40;</span>p3.<span style="color: #006600;">x</span>, p3.<span style="color: #006600;">y</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tr.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">lineTo</span><span style="color: #66cc66;">&#40;</span>p1.<span style="color: #006600;">x</span>, p1.<span style="color: #006600;">y</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tr.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//copy drawn shadows to bitmap texture</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; texture.<span style="color: #006600;">draw</span><span style="color: #66cc66;">&#40;</span>tr<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//addChild(tr);</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">clear</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Utils3D.<span style="color: #006600;">projectVectors</span><span style="color: #66cc66;">&#40;</span>projectionMatrix, vertices, projectedVerts, uvtData<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">beginBitmapFill</span><span style="color: #66cc66;">&#40;</span>texture,<span style="color: #000000; font-weight: bold;">null</span>, <span style="color: #000000; font-weight: bold;">false</span>, <span style="color: #000000; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawTriangles</span><span style="color: #66cc66;">&#40;</span>projectedVerts, indices, uvtData, TriangleCulling.<span style="color: #006600;">POSITIVE</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; container.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></div></td></tr></tbody></table></div>
<p>So although I was happy that this worked at all, it has some problems&#8230; performance has taken a hit, as we are re-creating the shadow/texture map every time. And the &#8216;texture map&#8217; a this point only has lighting in it , so we&#8217;d have to merge the lighting onto a real texture map (with other colors). And the sphere looks more like a disco ball, not smooth at all, so if we wanted a smooth appearance, we&#8217;d have to increase the number of points, which would further degrade performance. I did get some improvement by blurring the shadow-map but this would only help with smooth curved surfaces. So this is not a scalable solution at all. I almost didn&#8217;t want to show this version at all, but it does introduce the concept of normals, and how to get the lighting on a surface. </p>
<p>After a while it occurred to me that maybe I should really look into <a href="http://en.wikipedia.org/wiki/Normal_mapping">normal-maps</a> as a way to improve my lighting code. I was also hoping that I could optimize performance by using PixelBender to do the lighting calculations, based on the normal map. It turned out to be correct, so stay tuned for the next exciting installment&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dafishinsea.com/blog/2009/11/14/lighting-a-3d-object-in-flash-pt-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lighting a 3D object in Flash, pt 1</title>
		<link>http://www.dafishinsea.com/blog/2009/11/09/lighting-a-3d-object-in-flash-pt-1/</link>
		<comments>http://www.dafishinsea.com/blog/2009/11/09/lighting-a-3d-object-in-flash-pt-1/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 12:21:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[3d]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[flash]]></category>

		<guid isPermaLink="false">http://www.dafishinsea.com/blog/2009/11/09/lighting-a-3d-object-in-flash-pt-1/</guid>
		<description><![CDATA[This is the first part in a tutorial on using a normal map to light a sphere in Flash. 
First of all, we need some object to light.. for this I revisited the Sphere I did earlier, and improved the method of its construction, using radians instead of degrees, and also generating the indices in [...]]]></description>
			<content:encoded><![CDATA[<p>This is the first part in a tutorial on using a normal map to light a sphere in Flash. </p>
<p>First of all, we need some object to light.. for this I revisited the Sphere I did earlier, and improved the method of its construction, using radians instead of degrees, and also generating the indices in the same loop as the vertices. First, here is what it looks like with a flat, outlined fill&#8230;</p>
<p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="800" height="600" id="sphere"><param name="movie" value="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMap1.swf" /><param name="quality" value="high"/><param name="bgcolor" value="#000000"/><embed src="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMap1.swf" quality="high" bgcolor="#000000" width="800" height="600" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed></object></p>
<p> <a href="http://www.adobe.com/go/getflashplayer">flash 10 </a>required </p>
<p>Since I just installed the snazzy CodeColorer plugin, here&#8217;s the code&#8230;</p>
<div class="codecolorer-container actionscript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br /></div></td><td><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">package com.<span style="color: #006600;">dafishinsea</span>.<span style="color: #006600;">tutorials</span>.<span style="color: #006600;">normalmap</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">BitmapData</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">Sprite</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">TriangleCulling</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">events</span>.<span style="color: #006600;">Event</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Matrix3D</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">PerspectiveProjection</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Utils3D</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">geom</span>.<span style="color: #006600;">Vector3D</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #0066CC;">text</span>.<span style="color: #0066CC;">TextField</span>;<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp;* procedural model of a Pumpkin to demonstrate use of normal map<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#91;</span>SWF<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">backgroundColor</span>=<span style="color: #ff0000;">&quot;0x000000&quot;</span>, <span style="color: #0066CC;">width</span>=<span style="color: #ff0000;">&quot;800&quot;</span>, <span style="color: #0066CC;">height</span>=<span style="color: #ff0000;">&quot;600&quot;</span>, frameRate=<span style="color: #ff0000;">&quot;20&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> NormalMap1 <span style="color: #0066CC;">extends</span> Sprite<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> vertices:Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> projectedVerts:Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> numverts:<span style="color: #0066CC;">int</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> indices:Vector.<span style="color: #66cc66;">&lt;</span>int<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> uvts:Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> texture:BitmapData;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> perspective:PerspectiveProjection;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> projMatrix:Matrix3D;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> sphereRadius:<span style="color: #0066CC;">Number</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> sphereCenter:Vector3D;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> rows:<span style="color: #0066CC;">int</span>;<span style="color: #808080; font-style: italic;">//number of times the sphere is sliced to form segments</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> cols:<span style="color: #0066CC;">int</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> const <span style="color: #0066CC;">PI</span>:<span style="color: #0066CC;">Number</span> = <span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">PI</span>;<span style="color: #808080; font-style: italic;">//half revolution in radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> const HALFPI:<span style="color: #0066CC;">Number</span> = <span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">PI</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<span style="color: #808080; font-style: italic;">//1/4 revolution in radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> const TWOPI:<span style="color: #0066CC;">Number</span> = 2<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">PI</span>;<span style="color: #808080; font-style: italic;">//full revolution in radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> canvas:Sprite;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> r:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//the number of segments = num slices - 1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//this is the same as lines of longitude</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//thus there are twice as many as horizontal slices</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> NormalMap1<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; createMesh<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addEventListener<span style="color: #66cc66;">&#40;</span>Event.<span style="color: #006600;">ENTER_FRAME</span>, <span style="color: #0066CC;">onEnterFrame</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addEventListener<span style="color: #66cc66;">&#40;</span>Event.<span style="color: #006600;">RENDER</span>, render<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//render();</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #0066CC;">onEnterFrame</span><span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r = r + <span style="color: #cc66cc;">0.2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prerender<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">stage</span>.<span style="color: #006600;">invalidate</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* initialize common properties<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> init<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; perspective = root.<span style="color: #006600;">transform</span>.<span style="color: #006600;">perspectiveProjection</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; texture = <span style="color: #000000; font-weight: bold;">new</span> BitmapData<span style="color: #66cc66;">&#40;</span>800,800,<span style="color: #000000; font-weight: bold;">false</span>,0xCCCCCC<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sphereRadius = <span style="color: #cc66cc;">100</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//sphereCenter = new Vector3D(stage.stageWidth/2, stage.stageHeight/2, 200);</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cols = <span style="color: #cc66cc;">40</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rows = <span style="color: #cc66cc;">20</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; numverts = <span style="color: #66cc66;">&#40;</span>cols+1<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#40;</span>rows+1<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span>numverts<span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#41;</span>;<span style="color: #808080; font-style: italic;">//x,y,z for each vertex</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projectedVerts = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span>numverts<span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uvts = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>Number<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span>numverts<span style="color: #66cc66;">*</span>3<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indices = <span style="color: #000000; font-weight: bold;">new</span> Vector.<span style="color: #66cc66;">&lt;</span>int<span style="color: #66cc66;">&gt;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//we need to work around the fact that Utils3D.projectVectors disregards the projection center</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//of the projectionMatrix it is passed .. it always projects around 0,0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//so we must render things on a canvas centered on stage</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; canvas = <span style="color: #000000; font-weight: bold;">new</span> Sprite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; canvas.<span style="color: #006600;">x</span> = <span style="color: #0066CC;">stage</span>.<span style="color: #006600;">stageWidth</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; canvas.<span style="color: #006600;">y</span> = <span style="color: #0066CC;">stage</span>.<span style="color: #006600;">stageHeight</span><span style="color: #66cc66;">/</span><span style="color: #cc66cc;">2</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addChild<span style="color: #66cc66;">&#40;</span>canvas<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* create the mesh of the Sphere<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> createMesh<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lon_incr:<span style="color: #0066CC;">Number</span> = TWOPI<span style="color: #66cc66;">/</span>cols;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lat_incr = <span style="color: #0066CC;">PI</span><span style="color: #66cc66;">/</span>rows;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lon:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">0</span>;<span style="color: #808080; font-style: italic;">//angle of rotation around the y axis, *in radians*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> lat:<span style="color: #0066CC;">Number</span> = <span style="color: #cc66cc;">0</span>;<span style="color: #808080; font-style: italic;">//angle of rotation around the x axis</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> x:<span style="color: #0066CC;">Number</span>, y:<span style="color: #0066CC;">Number</span>, z:<span style="color: #0066CC;">Number</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> vnum:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> ind:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//a full rotation is PI radians</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> h:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>; h <span style="color: #66cc66;">&lt;</span>= rows; ++h<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y = sphereRadius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">cos</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<span style="color: #808080; font-style: italic;">//need to shift angle downwards by 1/4 rev</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> v:<span style="color: #0066CC;">int</span> = <span style="color: #cc66cc;">0</span>; v <span style="color: #66cc66;">&lt;</span>= cols; ++v<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x = sphereRadius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">cos</span><span style="color: #66cc66;">&#40;</span>lon<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; z = sphereRadius<span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lon<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #0066CC;">Math</span>.<span style="color: #0066CC;">sin</span><span style="color: #66cc66;">&#40;</span>lat<span style="color: #66cc66;">&#41;</span>;<span style="color: #808080; font-style: italic;">//seen from above, z = y</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//add vertex triplet</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>vnum<span style="color: #66cc66;">&#93;</span> = x;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>vnum+1<span style="color: #66cc66;">&#93;</span> = y;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vertices<span style="color: #66cc66;">&#91;</span>vnum+2<span style="color: #66cc66;">&#93;</span> = z;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vnum+=<span style="color: #cc66cc;">3</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">//add indices</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>h <span style="color: #66cc66;">&lt;</span> rows <span style="color: #66cc66;">&amp;&amp;</span> v <span style="color: #66cc66;">&lt;</span> cols<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indices.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span>ind, ind+1, ind + cols+1<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indices.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span>ind + cols+1, ind+1, ind + cols + 2<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ind+=<span style="color: #cc66cc;">1</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lon += lon_incr;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lat += lat_incr;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* prerender the sphere -- project vertices using rotated matrix<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> prerender<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projMatrix = perspective.<span style="color: #006600;">toMatrix3D</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projMatrix.<span style="color: #006600;">prependTranslation</span><span style="color: #66cc66;">&#40;</span>0,0,400<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; projMatrix.<span style="color: #006600;">prependRotation</span><span style="color: #66cc66;">&#40;</span>r, <span style="color: #000000; font-weight: bold;">new</span> Vector3D<span style="color: #66cc66;">&#40;</span>0,1,0<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Utils3D.<span style="color: #006600;">projectVectors</span><span style="color: #66cc66;">&#40;</span>projMatrix, vertices, projectedVerts,uvts<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* render<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> render<span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; canvas.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">clear</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; canvas.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">beginFill</span><span style="color: #66cc66;">&#40;</span>0xFFFFFF<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; canvas.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">lineStyle</span><span style="color: #66cc66;">&#40;</span>1,0xcccccc,1<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; canvas.<span style="color: #006600;">graphics</span>.<span style="color: #006600;">drawTriangles</span><span style="color: #66cc66;">&#40;</span>projectedVerts, indices, <span style="color: #000000; font-weight: bold;">null</span> <span style="color: #808080; font-style: italic;">/* uvts */</span>, TriangleCulling.<span style="color: #006600;">POSITIVE</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; canvas.<span style="color: #006600;">graphics</span>.<span style="color: #0066CC;">endFill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></div></td></tr></tbody></table></div>
<p>And if you actually want to download the code, here&#8217;s the link:</p>
<h4>Da Code</h4>
<p><a href="http://www.dafishinsea.com/fishpond/src/com/dafishinsea/tutorials/normalmap/NormalMap1.as">NormalMap1</a></p>
<p>(<a href="http://github.com/bigfish/fishpond/blob/master/src/com/dafishinsea/tutorials/normalmap/NormalMap1.as">@GitHub</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dafishinsea.com/blog/2009/11/09/lighting-a-3d-object-in-flash-pt-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>New Games Section</title>
		<link>http://www.dafishinsea.com/blog/2009/10/12/new-games-section/</link>
		<comments>http://www.dafishinsea.com/blog/2009/10/12/new-games-section/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 14:09:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[games]]></category>

		<guid isPermaLink="false">http://www.dafishinsea.com/blog/2009/10/12/new-games-section/</guid>
		<description><![CDATA[Just wanted to announce the launch of the new game section of the site. I added the Space Invaders game which is the first full-on &#8216;game engine&#8217; I&#8217;ve developed. I really wanted to preserve some effects from the original, such as the way the shields get gradually eroded by bullets. Ended up using the BitmapData [...]]]></description>
			<content:encoded><![CDATA[<p>Just wanted to announce the launch of the <a href="http://www.dafishinsea.com/games/">new game section of the site</a>. I added the <a href="http://www.dafishinsea.com/games/invaders/">Space Invaders game</a> which is the first full-on &#8216;game engine&#8217; I&#8217;ve developed. I really wanted to preserve some effects from the original, such as the way the shields get gradually eroded by bullets. Ended up using the BitmapData APIs a lot, both to create these effects, and also to avoid the high CPU usage effect that causes my MacBook to sound like a plane taking off whenever there&#8217;s more than a dozen sprites on stage and a semi-decent framerate. Another reason is the awesome Bitmap collision detection which is so fast and easy to do. I&#8217;ve tried doing games before, but ended up getting sidetracked by figuring out more and more complex collision detection &#8211; and never actually getting the game done &#8211;  until I realized that most of the arcade games that I love the most use only very simple collision detection. I know it&#8217;s a very basic game, and it was mostly an exercise in solving the basic problems involved in creating an arcade style game, but I still found myself actually enjoying testing it <img src='http://www.dafishinsea.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  So if you have nothing better to do, go ahead and play&#8230;no quarters required. **note &#8212; it has sound effects.. so you may want to grab some headphones to avoid annoying others.</p>
<p><a href="http://www.dafishinsea.com/games/invaders/"><br />
<img src="http://www.dafishinsea.com/images/invaders.png" alt="space invaders" /></a></p>
<p>Since Adobe announced the launch of Flash Player 10.1, targeting mobile devices, I&#8217;ve been thinking that such small casual games such as these are a good fit for mobile devices, so I will release mobile-sized versions, once I have a better idea of the target platforms&#8217; screen sizes. Then if any of the games get popular, I could also release a standalone AIR version for a small price for the serious addicts, which would provide better performance, screen size, and probably a few bonus features. Since I do have some commercial ambitions here, I&#8217;m not releasing the final game code in full, but I hope to document some of the more interesting techniques I&#8217;ve used, such as the dissolve effect, in later posts. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.dafishinsea.com/blog/2009/10/12/new-games-section/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cellular Automata Explorer</title>
		<link>http://www.dafishinsea.com/blog/2009/10/02/cellular-automata-explorer/</link>
		<comments>http://www.dafishinsea.com/blog/2009/10/02/cellular-automata-explorer/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 02:27:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[fractals]]></category>

		<guid isPermaLink="false">http://www.dafishinsea.com/blog/2009/10/02/cellular-automata-explorer/</guid>
		<description><![CDATA[So I&#8217;ve started on Stephen Wolfram&#8217;s epic tome, &#8216;A new Kind of Science&#8216;. I have known about Cellular Automata for some time.. I remember playing around with them in late High School, using BASIC. I went to the computer lab and got all the computers rendering different rules, producing different patterns. The machines were so [...]]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve started on Stephen Wolfram&#8217;s epic tome, &#8216;<a href="http://www.wolframscience.com/">A new Kind of Science</a>&#8216;. I have known about Cellular Automata for some time.. I remember playing around with them in late High School, using BASIC. I went to the computer lab and got all the computers rendering different rules, producing different patterns. The machines were so slow it took like five minutes for a single screen to be rendered.</p>
<p>So it is with some sense of familiarity and nostalgia that I look on these wedge shaped fractal patterns again.. and with great interest that I&#8217;m reading Mr Wolfram&#8217;s eloquent expositions of how they may be the key to understanding the universe. </p>
<p>Basically they work by evaluating each pixel in an image, and applying some rule which takes into account the values of surrounding pixels, and then changes the color of the pixel according to the rule. In the book, the simplest examples at the start just consider the pixel above the current one, and the pixels to the left and right. You can also think of this as applying the rule on the first row, placing the result in the second row, and then applying the rule to the second row and placing the result in the third, and so on. A rule may be something such as &#8216;if the pixels to the top-left and top-right of the pixel are black, make the pixel black&#8217;. </p>
<p>So after reading a bit, I felt inspired to code up some of the examples. After doing a <a href="http://wonderfl.net/code/d862ac3a7249a030bf43f474cc545f457a50e20f">few</a> of them I got to thinking that there must be a way to generalize them so that a single program could generate them. I was also thinking that binary/boolean arithmetic had to be helpful here somehow. The verbal descriptions seemed helpful at first, but were quite tricky to implement, requiring lots of if-then cases. After a while I had worked out a nice system of constructing the rule as an array of outcomes (either black or white). The array has 8 items &#8212; as there are 8 possible permutations of the 3  preceding rows pixels (the current pixel and its neighbours, in the previous row.)  If you visualize the index as a binary number, with the 1&#8217;s as black pixels and the 0&#8217;s as white, then you can translate the visual representation of the rules in the books (3 cells &#8212; the condition , or match, with the resulting pixel below) into simple numbers. This code probably is clearer than my explanation:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; //initial condition --&amp;gt; result<br />
&nbsp; &nbsp; &nbsp; &nbsp; rule[0] = WHITE; //000 -&amp;gt; white<br />
&nbsp; &nbsp; &nbsp; &nbsp; rule[1] = BLACK; //001 -&amp;gt; black<br />
&nbsp; &nbsp; &nbsp; &nbsp; rule[2] = BLACK; //010 -&amp;gt; black<br />
&nbsp; &nbsp; &nbsp; &nbsp; rule[3] = WHITE; //011 -&amp;gt; black<br />
&nbsp; &nbsp; &nbsp; &nbsp; rule[4] = BLACK; //100 -&amp;gt; black<br />
&nbsp; &nbsp; &nbsp; &nbsp; rule[5] = WHITE; //101 -&amp;gt; black<br />
&nbsp; &nbsp; &nbsp; &nbsp; rule[6] = WHITE; //110 -&amp;gt; white<br />
&nbsp; &nbsp; &nbsp; &nbsp; rule[7] = WHITE; //111 -&amp;gt; white</div></td></tr></tbody></table></div>
</pre>
<p>After that insight I was able to create an application that lets you toggle the rules (click to toggle the result). The rules are also numbered from 0-255, so you can enter the number in the input field, or click the next / previous buttons.</p>
<p> <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="800" height="500" id="cellularautomata"><param name="movie" value="http://dafishinsea.com/fishpond/src/com/dafishinsea/cellaut/CellularAutomataEngine.swf" /><param name="quality" value="high"/><param name="bgcolor" value="#FFFFFF"/><embed src="http://dafishinsea.com/fishpond/src/com/dafishinsea/cellaut/CellularAutomataEngine.swf" quality="high" bgcolor="#FFFFFF" width="800" height="500" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed></object></p>
<p> <a href="http://www.adobe.com/go/getflashplayer">flash 10 </a>required </p>
<p>As always, you can right-click and zoom in to see details&#8230;</p>
<h3>Da Code</h3>
<p><a href="http://github.com/bigfish/fishpond/blob/master/src/com/dafishinsea/cellaut/CellularAutomataEngine.as">CellularAutomataEngine.as</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dafishinsea.com/blog/2009/10/02/cellular-automata-explorer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
