<?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>Promethe's Blog &#187; 3D</title>
	<atom:link href="http://blog.promethe.net/tag/3d/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.promethe.net</link>
	<description>Web, RIAs and chocolate spaghettis...</description>
	<lastBuildDate>Tue, 29 Jun 2010 09:24:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>funanbulle, our #air24h application!</title>
		<link>http://blog.promethe.net/2010/06/24/funanbulle-our-air24h-application/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=funanbulle-our-air24h-application</link>
		<comments>http://blog.promethe.net/2010/06/24/funanbulle-our-air24h-application/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 15:10:16 +0000</pubDate>
		<dc:creator>Promethe</dc:creator>
				<category><![CDATA[Aerys]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[AIR 2.0]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[Minko]]></category>
		<category><![CDATA[RIA]]></category>

		<guid isPermaLink="false">http://blog.promethe.net/?p=836</guid>
		<description><![CDATA[The Adobe 24H Challenge was last friday and the application the 14 teams created are already online. You can see all the available applications on the official website. Our application is called "funanbulle". The goal of the application is to allow families to create their own micro virtual world and gather. We wanted to show [...]]]></description>
			<content:encoded><![CDATA[<p>The Adobe 24H Challenge was last friday and the application the 14 teams created are already online. You can see all the available applications on <a href="http://www.adobeairchallenge.com" target="_blank">the official website</a>.</p>
<p>Our application is called "funanbulle". The goal of the application is to allow families to create their own micro virtual world and gather. We wanted to show what such virtual worlds would look like. The idea was to enable people to share and chat in real time with a fun and engaging user experience.</p>
<div id="attachment_865" class="wp-caption aligncenter" style="width: 642px"><img class="size-full wp-image-865 " title="funanbulle_ingame" src="http://blog.promethe.net/wp-content/uploads/2010/06/funanbulle_ingame.jpg" alt="" width="632" height="452" /><p class="wp-caption-text">funanbulle, Aerys&#39; #air24h challenge contribution</p></div>
<p style="text-align: center;">
<p>The application is nothing more than a proof of concept. If we had enough time, we would have added lots of feature like:</p>
<ul>
<li>Audio chat</li>
<li>Photos and videos sharing</li>
<li>Interactive objects to trigger applications (games, sharing applications, etc...)</li>
</ul>
<p>In the end, we had just enough time to build a 3D chat. But I think it was a lot of fun and it looks really nice! Here is a quick video to show what funanbulle is about and how it works:</p>
<p><center><br />
<object width="400" height="250"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=12924419&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=12924419&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="250"></embed></object><br />
</center></p>
<p>This video was made by <a href="http://codemoiunmouton.wordpress.com/" target="_blank">Michael Chaize</a> to show the 14 applications created during the contest.</p>
<p><span id="more-836"></span></p>
<p>To install the application, just click on the following picture to go to the install badge:</p>
<p><a rel="shadowbox;width=400;height=300;background=#ffffff" href="http://www.adobeairchallenge.com/applications/install/?teamid=1&amp;appliName=FUNANBULLE&amp;appliUrl=aerys-funanbulle.air&amp;appliBadge=badge-aerys.jpg" target="_blank"><img class="aligncenter size-full wp-image-854" title="funanbulle_badge" src="http://blog.promethe.net/wp-content/uploads/2010/06/funanbulle_badge.jpg" alt="" width="217" height="130" /></a></p>
<p>When the application starts, you will be asked to "join" or "create" a room:</p>
<p><img class="aligncenter size-full wp-image-858" title="funanbulle_menu" src="http://blog.promethe.net/wp-content/uploads/2010/06/funanbulle_menu.jpg" alt="" width="632" height="452" /></p>
<ul>
<li>If you don't have a room number: select "create a room" to create a new room. When the room is created, you'll join in automatically join it. The room number will be visible in the top right corner. You can share it with your friends and family to enable them joining your room.</li>
<li>If you have a room number (because a friend already created a room and gave you its number for example): select "join a room", type your room number and click "Go". And voilà!</li>
</ul>
<p>You can use the bottom text input to chat with your friends. But you can also launch special actions by typping one of the following commands:</p>
<ul>
<li>/jump</li>
<li>/wait</li>
<li>/sit</li>
<li>/use</li>
<li>/wave</li>
</ul>
<p>We hope you'll like it and have fun with it!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.promethe.net/2010/06/24/funanbulle-our-air24h-application/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Pixel shader demo using Flash 10, Pixel Bender and Minko</title>
		<link>http://blog.promethe.net/2010/06/09/pixel-shader-demo-using-flash-10-pixel-bender-and-minko/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=pixel-shader-demo-using-flash-10-pixel-bender-and-minko</link>
		<comments>http://blog.promethe.net/2010/06/09/pixel-shader-demo-using-flash-10-pixel-bender-and-minko/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 12:42:47 +0000</pubDate>
		<dc:creator>Promethe</dc:creator>
				<category><![CDATA[Aerys]]></category>
		<category><![CDATA[Minko]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[ActionScript 3.0]]></category>
		<category><![CDATA[Flash 10]]></category>
		<category><![CDATA[Flash 10.1]]></category>

		<guid isPermaLink="false">http://blog.promethe.net/?p=770</guid>
		<description><![CDATA[I'm really excited to announce Minko (which is, by the way, the final name for my 3D library) has reached a new level: pixel shader integration! Pixel shaders are little programs that run on each pixel and can modify their final color. They are often written in C-like languages and in this precise case we [...]]]></description>
			<content:encoded><![CDATA[<p>I'm really excited to announce Minko (which is, by the way, the final name for my 3D library) has reached a new level: pixel shader integration! Pixel shaders are little programs that run on each pixel and can modify their final color. They are often written in C-like languages and in this precise case we use Pixel Bender, the shader language introduced with Flash 10.</p>
<p>In this post I will:</p>
<ul>
<li>Explain how any 3D scene is built when using Minko</li>
<li>Explain how pixel shaders are integrated in the 3D scene</li>
<li>Explain how pixel shaders are built using Pixel Bender</li>
<li>Show you a very simple demo of the kind of effects pixel shaders will provide</li>
<li>Explain how the demo was built</li>
</ul>
<p>Here are a two screenshots to show the results:</p>
<div id="attachment_824" class="wp-caption aligncenter" style="width: 650px"><a href="http://blog.promethe.net/wp-content/uploads/2010/06/minko_lamborghini.jpg" rel="shadowbox[post-770];player=img;"><img class="size-full wp-image-824 " title="minko_lamborghini" src="http://blog.promethe.net/wp-content/uploads/2010/06/minko_lamborghini.jpg" alt="" width="640" height="360" /></a><p class="wp-caption-text">Phong shading + spheric environment mapping on a 2700+ polygons Lamborghini</p></div>
<div id="attachment_782" class="wp-caption aligncenter" style="width: 508px"><a href="http://blog.promethe.net/wp-content/uploads/2010/06/minko_phong_1.jpg" rel="shadowbox[post-770];player=img;"><img class="size-full wp-image-782 " title="minko_phong_1" src="http://blog.promethe.net/wp-content/uploads/2010/06/minko_phong_1.jpg" alt="" width="498" height="373" /></a><p class="wp-caption-text">Phong shading + spheric environment mapping demo</p></div>
<p><span id="more-770"></span></p>
<h4>The Scene Graph API</h4>
<p>This API is used to build and manage the 3D scene. Scene graph is the most common data-structure used to build 3D scenes. It is simple to understand and both memory wise and CPU efficient. To explain what the scene graph is, start thinking about Flash's display list. In ActionScript 3.0, the display list is actually a tree. The root of the tree is the Stage and you can add multiple children to it. Each child can be a leaf, such as a Bitmap object, or a container such as a Sprite. One of the limitations of a tree is that every node can have multiple children but each child can have only one parent. This property is what makes it look like a tree: branches (and leaves for that matter...) have only one parent branch.</p>
<p>A direct consequence of that paradigm is that if you want 20 red circles, you will have to create 20 red circles and add them to the display tree. Despite the fact that those 20 red circles will be exactly the same you will still have to create and add all of them to the display tree. Thus, you will use 19 times more memory than what is actually needed. That's where the graph kicks in...</p>
<p>A graph is just like a tree except every node can have multiple parents. You can see graphs as a generalization of trees. But you can also say that trees are particular graphs where each node can have only one parent. Anyway, we can now create one red circle and use it as many times as we need! To understand how this apply to a 3D scene, lets consider the following rendering:</p>
<p><a href="http://blog.promethe.net/wp-content/uploads/2010/06/minko_scene_graph_demo.jpg" rel="shadowbox[post-770];player=img;"><img class="aligncenter size-full wp-image-771" title="minko_scene_graph_demo" src="http://blog.promethe.net/wp-content/uploads/2010/06/minko_scene_graph_demo.jpg" alt="" width="413" height="308" /></a></p>
<p>And here is the corresponding scene graph:</p>
<p><a href="http://blog.promethe.net/wp-content/uploads/2010/06/minko_scene_graph.jpg" rel="shadowbox[post-770];player=img;"><img class="aligncenter size-medium wp-image-786" title="minko_scene_graph" src="http://blog.promethe.net/wp-content/uploads/2010/06/minko_scene_graph-300x176.jpg" alt="" width="300" height="176" /></a></p>
<p>There are five things to notice:</p>
<ol>
<li>The figure doesn't show the whole graph (I removed the camera and materials).</li>
<li><strong>The Scene Graph API is all about interfaces</strong>. You can add new features to the API and still extend the classes you need/want (ie. EventDispatcher).</li>
<li>The CubeMesh.cubeMesh, SquareMesh.squareMesh and SphereMesh.sphereMesh nodes, which contain the primitives geometry, exist only once each but are used by many IDisplayObject3D. Therefore there is <strong>no useless memory consumption</strong>! The same can be done with any node in the graph: containers, display objects, materials, etc...</li>
<li>The orange circled <strong>nodes apply a (3D) transformation to their children</strong>, just like Flash containers apply (2D) transformations to their own children.</li>
<li><strong>Z-Sorting is here enabled by two different technics</strong>: the <strong>drawing order</strong> (which is pretty much the same as in a classic-2D-Flash display tree) and the <strong>DepthSortContainer3D</strong> node. This node takes care of z-sorting by sorting its children using their average depth. This way, <strong>z-sorting occurs only when needed</strong> and only on relevant geometry.</li>
</ol>
<p>There a lot to explain about the Scene Graph API! But the main point is to understand how it compares to Flash's display tree and what benefits it provides: <strong>lower memory consumption and powerful scene building</strong>. You are likely to need to find a way to fit in the Scene Graph API anytime you want to extend Minko to add a new feature. In this precise case I will talk about how pixel shaders fits in.</p>
<h4>Pixel shader integration</h4>
<p>The first step is to find "where" in the graph your new feature will be used. Close to the scene "root" you will more likely find containers. And the "leaves" are often more tangible objects such as a materials or meshes. A pixel shader is some kind of a material so that's where we should start looking!</p>
<p>In the Scene Graph API, there is a special way to handle materials: the "<strong>material stack</strong>". It's a part of the graph - a subgraph really - that looks very much like a stack because every node uses an "underlaying" material node. Lets consider the orange box from the previous example:</p>
<p><a href="http://blog.promethe.net/wp-content/uploads/2010/06/minko_scene_graph_material.jpg" rel="shadowbox[post-770];player=img;"><img class="aligncenter size-full wp-image-790" title="minko_scene_graph_material" src="http://blog.promethe.net/wp-content/uploads/2010/06/minko_scene_graph_material.jpg" alt="" width="424" height="348" /></a></p>
<p>This figure shows the orange cube subgraph. On this graph I added the material nodes to demonstrate how the material stack works. In this precise case, the stack is made of a WireframeMaterial node and a SolidMaterial node. The first one provides a wireframe rendering and the second one is a solid fill. When rendering, <strong>the resulting graphics operations will be the list of all the graphics instructions outputed by each node of the stack</strong>. Thus, we will here obtain an (orange) solid fill with a (purple) wireframe. So where does the pixel shader fits in the material stack? Well you might have noticed there are two different kinds of nodes in the material stack:</p>
<ol>
<li>the bottom of the stack is more likely to be a "<strong>base material</strong>", like a solid fill or a texture</li>
<li>and the rest of the stack will be mainly "<strong>modifiers</strong>". In the case of the orange cube, the WireframeMaterial node acts as a modifier for the SolidMaterial node</li>
</ol>
<p><strong>Our pixel shader material will be a modifier</strong> because it will work on an underlaying texture. Now we know our pixel shader material should be on the top of the material stack we have to know what data it needs and how to provide it!</p>
<h4>Pixel shader creation using Pixel Bender</h4>
<p>A pixel shader works at the pixel level (true story). Therefore, <strong>we need per-pixel data</strong>. But because we use Flash's drawing API we don't have a direct access to the actual pixels (I'm oversimplifying but that's the idea). The trick is to <strong>work on the material BitmapData itself rather than the screen pixels</strong>. Thus, I will now talk about "<strong>texels</strong>" (texture pixels) rather than pixels (so I guess it should be called a "texel shader" then...). Anyway, <strong>our shader will then most certainly always need three inputs</strong>:</p>
<ol>
<li>The color of each texel, also called a "<strong>diffuse map</strong>" or... a texture. Any material will do the trick (we can get a BitmapData out of any material).</li>
<li>The position of each texel, also called a "<strong>position map</strong>".</li>
<li>The normal of each texel, also called a "<strong>normal map</strong>".</li>
</ol>
<p>The position map will be generated at runtime. It is mainly a BitmapData where <strong>each pixel stores the (x, y, z) values of the position</strong> of the corresponding texel instead of an (r, g, b) color value. The normal map can be generated at runtime. It can also be any material as long as it provides a relevant BitmapData. This BitmapData stores <strong>the (nx, ny, nz) values of the normal</strong> of the corresponding texel. Here is an example:</p>
<p><a href="http://blog.promethe.net/wp-content/uploads/2010/06/minko_maps_generation.jpg" rel="shadowbox[post-770];player=img;"><img class="aligncenter size-medium wp-image-777" title="minko_maps_generation" src="http://blog.promethe.net/wp-content/uploads/2010/06/minko_maps_generation-300x85.jpg" alt="" width="300" height="85" /></a></p>
<p>In this example both the normal and the position maps have been generated using Minko's NormalMap and PositionMap classes. This picture is actually a screenshot of a demo Flash application. I wont talk too much about this generation step for now, but its done using Pixel Bender and its lighting fast!</p>
<p>In order to make this data available to any pixel shader, the diffuse, normal and position maps are stored in a one-and-only scene graph node: the <strong>PixelMaterial</strong>. This node will then provide <strong>per-texel data access</strong> to its modifiers. We can now implement a real pixel shader on top of any PixelMaterial! Everything we need now is a <strong>Pixel Bender kernel that takes our 3 maps (diffuse, position and normal) in input</strong>.</p>
<p>The following Pixel Bender filter performs <a href="http://en.wikipedia.org/wiki/Phong_shading" target="_blank">Phong shading</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="pixelbender" style="font-family:monospace;"><span style="color: #0033ff;">void</span>
<span style="color: #0033ff; font-weight: bold;">evaluatePixel</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
        <span style="color: #0033ff;">float2</span> o <span style="color: #000000; font-weight: bold;">=</span> <span style="color: #333333;">outCoord</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
        <span style="color: #0033ff;">float3</span> position <span style="color: #000000; font-weight: bold;">=</span> <span style="color: #333333;">sampleNearest</span><span style="color: #000000;">&#40;</span>positionMap, o<span style="color: #000000;">&#41;</span>;
        <span style="color: #0033ff;">float3</span> normal <span style="color: #000000; font-weight: bold;">=</span> <span style="color: #333333;">sampleNearest</span><span style="color: #000000;">&#40;</span>normalMap, o<span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">*</span> 2. <span style="color: #000000; font-weight: bold;">-</span> ONE;
        <span style="color: #0033ff;">float3</span> light <span style="color: #000000; font-weight: bold;">=</span> <span style="color: #333333;">normalize</span><span style="color: #000000;">&#40;</span>light <span style="color: #000000; font-weight: bold;">-</span> position<span style="color: #000000;">&#41;</span>;
&nbsp;
        <span style="color: #009900;">// ambient</span>
        <span style="color: #0033ff;">float</span> l <span style="color: #000000; font-weight: bold;">=</span> ambient <span style="color: #000000; font-weight: bold;">*</span> intensity;
&nbsp;
        <span style="color: #009900;">// diffuse</span>
        l <span style="color: #000000; font-weight: bold;">+=</span> <span style="color: #333333;">max</span><span style="color: #000000;">&#40;</span>0., <span style="color: #333333;">dot</span><span style="color: #000000;">&#40;</span>light, normal<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">*</span> diffuse <span style="color: #000000; font-weight: bold;">*</span> intensity;
&nbsp;
        dst <span style="color: #000000; font-weight: bold;">=</span> <span style="color: #333333;">sampleNearest</span><span style="color: #000000;">&#40;</span>diffuseMap, o<span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #0033ff;">float4</span><span style="color: #000000;">&#40;</span>l, l, l, 1.<span style="color: #000000;">&#41;</span>;
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>As you can see its really straight forward. This is due to the Scene Graph API which makes it possible to <strong>do every computation in local space</strong>. Therefore we don't have to care about where those computations happen in the 3D scene.</p>
<h4>Demo</h4>
<p><a href="http://en.wikipedia.org/wiki/Phong_shading" target="_blank">Phong shading</a> or <a href="http://en.wikipedia.org/wiki/Reflection_mapping" target="_blank">reflection mapping</a> are great examples of pixel shaders. The following demo uses both (the white diamond stands for the light source):</p>
<div id="attachment_779" class="wp-caption aligncenter" style="width: 648px"><a href="http://blog.promethe.net/wp-content/uploads/2010/06/PixelShaderDemo.swf" rel="shadowbox[post-770];width=640;height=385;"><img class="size-full wp-image-779 " title="minko_phong_cubic" src="http://blog.promethe.net/wp-content/uploads/2010/06/minko_phong_cubic.jpg" alt="" width="638" height="359" /></a><p class="wp-caption-text">Phong shading + spheric environment mapping demo</p></div>
<div id="attachment_797" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.promethe.net/wp-content/uploads/2010/06/minko_scene_graph_phong_spheric.jpg" rel="shadowbox[post-770];player=img;"><img class="size-medium wp-image-797 " title="minko_scene_graph_phong_spheric" src="http://blog.promethe.net/wp-content/uploads/2010/06/minko_scene_graph_phong_spheric-300x229.jpg" alt="" width="300" height="229" /></a><p class="wp-caption-text">Phong shading + spheric environment mapping scene graph</p></div>
<p style="text-align: left;">And to put it in a nutshell, a few performances considerations:</p>
<ul>
<li>Everything is done in <strong>real time</strong>.</li>
<li>Thanks to the Scene Graph API, <strong>every computation is done in local space</strong>. It avoids matrix multiplications by the thousand and gives a significant performance boost.</li>
<li>The application takes <strong>less than 20Mb of memory</strong> and weights less than 100Kb.</li>
<li>There are a total of <strong>6 pixel shaders run at each frame</strong> (only the visible faces materials are computed and there are 2 shaders per face).</li>
<li>Those shaders work on <strong>128*128 pixels diffuse/normal/position maps</strong></li>
<li>That's a total of <strong>98,304 pixels per frame</strong></li>
<li>Each frame is <strong>"processed" in an average of 10ms.</strong> (Core2 Duo U9400 @ 1.4Ghz, Flash 10.1 RC7, Chrome 5)</li>
<li>That's <strong>9,830,400 pixels per second!</strong></li>
<li>There is a <strong>~30% performance boost with Flash 10.1 RC7</strong></li>
<li><strong>The number of triangles does not impact the performances</strong></li>
<li>Do not hesitate to post your own results (with your configuration of course)! <img src='http://blog.promethe.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </li>
</ul>
<p style="text-align: left;">
]]></content:encoded>
			<wfw:commentRss>http://blog.promethe.net/2010/06/09/pixel-shader-demo-using-flash-10-pixel-bender-and-minko/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Video of the Minko presentation at the TTFX barcamp</title>
		<link>http://blog.promethe.net/2010/06/01/video-of-the-minko-presentation-at-the-ttfx-barcamp/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=video-of-the-minko-presentation-at-the-ttfx-barcamp</link>
		<comments>http://blog.promethe.net/2010/06/01/video-of-the-minko-presentation-at-the-ttfx-barcamp/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 12:42:12 +0000</pubDate>
		<dc:creator>Promethe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[barcamp]]></category>
		<category><![CDATA[Minko]]></category>
		<category><![CDATA[Tontons Flexeurs]]></category>

		<guid isPermaLink="false">http://blog.promethe.net/?p=747</guid>
		<description><![CDATA[Here is a link to my first official presentation of Minko, the 3D library I am working on (and which was previously called "DirectFlex"): This video was shot the 23rd of March by the people from BAAO. A very big thank you to Yann Chevalier, who's leading the TTFX effort, Michael Chaize, our awesome french [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a link to my first official presentation of Minko, the 3D library I am working on (and which was previously called "DirectFlex"):</p>
<p><a href="http://www.baao.com/Video/Minko_3D.html" target="_blank"><img class="aligncenter size-full wp-image-748" title="minko_ttfx_20090323" src="http://blog.promethe.net/wp-content/uploads/2010/05/minko_ttfx_20090323.jpg" alt="" width="600" height="340" /></a></p>
<p>This video was shot the 23rd of March by the people from BAAO. A very big thank you to Yann Chevalier, who's leading the TTFX effort, Michael Chaize, our awesome french Flash platform evangelist and Olivier from BAAO who gave me the link to the video.</p>
<p>You can find the slides <a href="http://promethe.net/slides/ttfx_minko_20100323.pdf" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.promethe.net/2010/06/01/video-of-the-minko-presentation-at-the-ttfx-barcamp/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Flash 11 drawing API will be hardware accelerated</title>
		<link>http://blog.promethe.net/2010/04/19/flash-11-will-be-hardware-accelerated/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=flash-11-will-be-hardware-accelerated</link>
		<comments>http://blog.promethe.net/2010/04/19/flash-11-will-be-hardware-accelerated/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 13:42:39 +0000</pubDate>
		<dc:creator>Promethe</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Flash 10.1]]></category>
		<category><![CDATA[hardware acceleration]]></category>

		<guid isPermaLink="false">http://blog.promethe.net/?p=724</guid>
		<description><![CDATA[I love catchy titles. I know nothing about the next major version of Flash and all of this is just speculations. Anyway, as the whole HTML5 versus Flash battle is raging, it appears Flash relatively poor performances are indeed criticizable at best. Beside poor developers, the Flash Platform suffers from a very very slow software [...]]]></description>
			<content:encoded><![CDATA[<p>I love catchy titles. I know nothing about the next major version of Flash and all of this is just speculations.</p>
<p>Anyway, as the whole HTML5 versus Flash battle is raging, it appears Flash relatively poor performances are indeed criticizable at best. Beside poor developers, the Flash Platform suffers from a very very slow software renderer. Or at least much slower than the rest of the platform. It's no secret: hardware acceleration is a key feature for the future of the Flash Player. It's even hard to believe it is not available yet!</p>
<p>As you must already know, Flash 10.1 will support OpenGL ES 2 on mobile devices to leverage the lack of CPU horsepower. While hardware HD video decoding will be available on the desktop too, the drawing API will only be accelerated on mobile devices.</p>
<p>Anyone knowing a bit about OpenGL ES knows it is a subset of OpenGL. Thus if it works with OpenGL ES, it <em>should</em> work with OpenGL. With this in mind, a few questions:</p>
<ol>
<li>Why isn't Flash 10.1 drawing API hardware accelerated on any OpenGL capable platform, including the desktop?</li>
<li>How will it work?</li>
<li>Will Pixel Bender be hardware accelerated?</li>
</ol>
<h4>1. Hardware Accelerated Desktop Flash Player</h4>
<p>Let's face it: there <strong>must be</strong> an hardware accelerated desktop Flash Player in the works. As I said previously, OpenGL supports all features of OpenGL ES so this is not far fetched at all. Yet, it is neither released nor announced. Why?</p>
<p>My first guess is OpenGL provides with a lot of features that would make the desktop experience a lot smoother than just using what offers its little brother OpenGL ES. So at some point Adobe had to make a choice :</p>
<ul>
<li>release a fully hardware accelerated Flash 10.1 on both mobile and desktop platforms, with the last one being very far from what desktop hardware is actually capable to handle</li>
<li>or release Flash 10.1 focusing on mobile devices and announce hardware acceleration for the desktop just after its the final release... and I'm guessing it might be a key feature of Flash 11</li>
</ul>
<p>When I was at the French Flash User Group (TTFX - les TonTons FleXeurs) a few months ago, I spoke with Lee Brimelow and Mike Chambers about the just announced microphone raw-data access. I asked them why it was announced only for AIR 2.0 and not Flash 10.1. The answer was something about the "quality guys" making sure the feature was well suited on both the roadmap and the logic of the incoming updates. And this feature eventually made its way into the Flash Player! I think that's what is happening with hardware acceleration on the desktop.</p>
<p>But if you don't believe me, you don't have to take my word for it! What about Adobe's word? Cnuuja, one of the engineer working on the Flash Player, posted this very message on the Flash 10.1 Forum:</p>
<p><a href="http://forums.adobe.com/message/2742943#2742943">Can OpenGL 3.3/4.0 improve Flash 10.x ?</a></p>
<p><em>"Yes....  with a lot of work.   We have spent the last year writing new code which allows OpenGLES2 to render flash content on mobile devices.  Performance varies significantly from one gpu to the next, with some gpus being slower than the software renderer.   What Flash does is significantly different from the 3d triangles+shaders GPUs were designed to support. </em><strong><em>Its a lot of work to make OGL/D3D usable as our renderer, but we're working on it <img src="http://wwwimages.adobe.com/www.adobe.com/adobeforums/images/emoticons/happy.gif" alt="" width="16px" height="16px" /></em></strong></p>
<p><em>-chris"</em></p>
<h4>2. How will it work?</h4>
<p>Just like in Flash 10.1 for mobile devices. But much faster thanks to OpenGL and Direct3D.</p>
<p>The internals of such feature is very important: developers must know and understand how it works to make the best out of it. <a href="http://www.adobe.com/devnet/flashplayer/articles/fplayer10.1_hardware_acceleration_05.html" target="_blank">Adobe already talked about how the drawing API is accelerated in Flash 10.1</a> on mobile devices:</p>
<p><em>"When a GPU renders vector graphics, it breaks them up into meshes made of small triangles before drawing them, a process called tesselating. There is a small cost to doing this, which increases as the complexity of the shape increases. To minimize performance impact, avoid morph shapes, which must be retesselated on every frame."</em></p>
<p>It's straight forward and I think it's actually the best (and only...) way to do it. Tesselation will create triangles by computing sets of vertices/indices (also called Vertex and Index Buffers) and push them to the graphics hardware. The end of the quote suggests such data is cached and should not be recomputed if no redraw occurs.</p>
<p>Something very important though: z-sorting. People might think hardware acceleration implies z-sorting. But it doesn't. When you know how 3D hardware and APIs work, you know it will be very tricky to make it work with something as general purpose as Flash. If Adobe wants to use the z-buffer, they will have to cut the compatibility with the software renderer. And I don't think this will happen anytime soon.</p>
<h4>3. Hardware Accelerated Pixel Bender</h4>
<p>Pixel Bender is already hardware accelerated pretty much everywhere except the Flash Platform. I'm not sure why. Still, it's hardware accelerated in other products of the Creative Suite so I guess that an OpenGL/Direct3D shader languages compliant intermediate represenation of Pixel Bender kernels does exist.</p>
<p>This said, it's just a matter of how to make it work with the very general purpose Flash Player. Considering Flash 10.1 is using tesselation, my guess is pixel shader should follow quite easily.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.promethe.net/2010/04/19/flash-11-will-be-hardware-accelerated/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Frustum Culling in Flash 10</title>
		<link>http://blog.promethe.net/2009/12/13/frustum-culling-in-flash-10/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=frustum-culling-in-flash-10</link>
		<comments>http://blog.promethe.net/2009/12/13/frustum-culling-in-flash-10/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 15:43:05 +0000</pubDate>
		<dc:creator>Promethe</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[ActionScript 3.0]]></category>
		<category><![CDATA[experiment]]></category>
		<category><![CDATA[Flash 10]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.promethe.net/?p=558</guid>
		<description><![CDATA[Update: corrected a few glitches in the bounding sphere creation routine. Optimization is always important. But when it comes to 3D for the Flash Platform, it's an everyday battle. The first ideas that come to mind are to avoid: redrawing the same regions : each pixel value must be set once and only once rendering [...]]]></description>
			<content:encoded><![CDATA[<p><strong><span style="color:#ff0000">Update:</span></strong> corrected a few glitches in the bounding sphere creation routine.</p>
<p>Optimization is always important. But when it comes to 3D for the Flash Platform, it's an everyday battle. The first ideas that come to mind are to avoid:</p>
<ol>
<li>redrawing the same regions : each pixel value must be set once and only once</li>
<li>rendering invisible objects : objects that are out of sight still take a lot of CPU horsepower</li>
</ol>
<p>While Flash takes care of the first one in its very renderer, the second one is not handled. But that is something we can easily address!</p>
<h4 style="text-align: left;">The Technic</h4>
<p>The method is called "frustum culling". The big picture is that every mesh is approximated using a bounding volume (typically a sphere or a box). If the bounding volume is visible, the corresponding mesh is rendered. The two following pictures show the frustum culling caught in action:</p>
<div id="attachment_569" class="wp-caption aligncenter" style="width: 510px"><a href="http://blog.promethe.net/wp-content/uploads/2009/12/frustum_culling_scene.PNG" rel="shadowbox[post-558];player=img;"><img class="size-full wp-image-569" title="frustum_culling_scene" src="http://blog.promethe.net/wp-content/uploads/2009/12/frustum_culling_scene.PNG" alt="The mesh is visible" width="500" height="375" /></a><p class="wp-caption-text">The mesh is visible: TPS counter indicates 18900 triangles per seconds</p></div>
<div id="attachment_568" class="wp-caption aligncenter" style="width: 510px"><a href="http://blog.promethe.net/wp-content/uploads/2009/12/frustum_culling_acting.PNG" rel="shadowbox[post-558];player=img;"><img class="size-full wp-image-568" title="frustum_culling_acting" src="http://blog.promethe.net/wp-content/uploads/2009/12/frustum_culling_acting.PNG" alt="Frustum culling in action (TPS counter indicates 0!)" width="500" height="375" /></a><p class="wp-caption-text">The mesh is out of sight: frustum culling is acting and TPS counter indicates 0!</p></div>
<p><span id="more-558"></span></p>
<h5>1. The frustum</h5>
<p>First things first: before performing frustum culling, you need to build the frustum! The frustum is the 3D shape that contains everything the camera can see. It's made of 6 planes and looks like a truncated pyramid:</p>
<div id="attachment_563" class="wp-caption aligncenter" style="width: 517px"><a href="http://blog.promethe.net/wp-content/uploads/2009/12/view_frustum.png" rel="shadowbox[post-558];player=img;"><img class="size-full wp-image-563" title="view_frustum" src="http://blog.promethe.net/wp-content/uploads/2009/12/view_frustum.png" alt="The view frustum" width="507" height="302" /></a><p class="wp-caption-text">The view frustum</p></div>
<p>Each plane is defined by a plane equation: ax + by + cz + d, where (a, b, c) is the normal of the plane and d the distance on that normal. The 6 planes must be extracted from one of the Matrix3D object used to define the transform from one space to another (world to camera for example). Here are the 6 plane equations:</p>
<ul>
<li>left: (a = m14 + m11, b = m24 + m21, c = m34 + m31, d = m44 + m41)</li>
<li>right: (a = m14 − m11, b = m24 − m21, c = m34 − m31, d = m44 − m41)</li>
<li>bottom: (a = m14 + m12, b = m24 + m22, c = m34 + m32, d = m44 + m42)</li>
<li>top: (a = m14 − m12, b = m24 − m22, c = m34 − m32, d = m44 − m42)</li>
<li>near: (a = m13, b = m23, c = m33, d = m43)</li>
<li>far: (a = m13, b = m23, c = m33, d = m43)</li>
</ul>
<p>The source matrix you chose defines the coordinates systems of the extracted planes:</p>
<ul>
<li>the projection matrix provides planes in view (or camera) space</li>
<li>the view * projection matrix provides planes in world space</li>
<li>the world * view * projection matrix provides planes in object (or local) space</li>
</ul>
<h5>2. Bounding volumes</h5>
<p>Testing every polygon against the frustum is a very expensive task. In order to speed things up, we will rather test a primitive shape that bounds the mesh: a "bounding volume". Common bounding volumes are spheres or boxes. I'll focus on the first one in the rest of the article.</p>
<p>A bounding sphere is pretty simple to implement: you just need to store the center of the sphere and it's radius. That being said, a BoundingSphere class would just contain the center as a Vector3D and the radius as a Number. When you have all the vertices of a mesh, building the bounding sphere is easy :</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> computeBoundingSphere<span style="color: #000000;">&#40;</span>myVertices <span style="color: #000000; font-weight: bold;">:</span> Vector.<span style="color: #000000; font-weight: bold;">&lt;</span>Number<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">:</span> BoundingSphere
<span style="color: #000000;">&#123;</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">min</span> <span style="color: #000000; font-weight: bold;">:</span> Vector3D = <span style="color: #0033ff; font-weight: bold;">new</span> Vector3D<span style="color: #000000;">&#40;</span><span style="color: #004993;">Number</span>.<span style="color: #004993;">MAX_VALUE</span>, <span style="color: #004993;">Number</span>.<span style="color: #004993;">MAX_VALUE</span>, <span style="color: #004993;">Number</span>.<span style="color: #004993;">MAX_VALUE</span><span style="color: #000000;">&#41;</span>;
	<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">max</span> <span style="color: #000000; font-weight: bold;">:</span> Vector3D = <span style="color: #0033ff; font-weight: bold;">new</span> Vector3D<span style="color: #000000;">&#40;</span><span style="color: #004993;">Number</span>.<span style="color: #004993;">MIN_VALUE</span>, <span style="color: #004993;">Number</span>.<span style="color: #004993;">MIN_VALUE</span>, <span style="color: #004993;">Number</span>.<span style="color: #004993;">MIN_VALUE</span><span style="color: #000000;">&#41;</span>;
	<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">length</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">int</span> = myVertices.<span style="color: #004993;">length</span>;
	<span style="color: #6699cc; font-weight: bold;">var</span> center <span style="color: #000000; font-weight: bold;">:</span> Vector3D = <span style="color: #0033ff; font-weight: bold;">null</span>;
	<span style="color: #6699cc; font-weight: bold;">var</span> radius <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = <span style="color: #0033ff; font-weight: bold;">null</span>;
&nbsp;
	<span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #000000;">&#40;</span><span style="color: #6699cc; font-weight: bold;">var</span> i <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">uint</span> = <span style="color: #000000; font-weight:bold;">0</span>; i <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #004993;">length</span>; i <span style="color: #000000; font-weight: bold;">+</span>= <span style="color: #000000; font-weight:bold;">3</span><span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		<span style="color: #004993;">min</span>.<span style="color: #004993;">x</span> = myVertices <span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #004993;">min</span>.<span style="color: #004993;">x</span> <span style="color: #000000; font-weight: bold;">?</span> myVertices<span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">min</span>.<span style="color: #004993;">x</span>;
		<span style="color: #004993;">min</span>.<span style="color: #004993;">y</span> = myVertices <span style="color: #000000;">&#91;</span><span style="color: #004993;">uint</span><span style="color: #000000;">&#40;</span>i <span style="color: #000000; font-weight: bold;">+</span> <span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #004993;">min</span>.<span style="color: #004993;">y</span> <span style="color: #000000; font-weight: bold;">?</span> myVertices<span style="color: #000000;">&#91;</span><span style="color: #004993;">int</span><span style="color: #000000;">&#40;</span>i <span style="color: #000000; font-weight: bold;">+</span> <span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">min</span>.<span style="color: #004993;">y</span>;
		<span style="color: #004993;">min</span>.z = myVertices <span style="color: #000000;">&#91;</span><span style="color: #004993;">uint</span><span style="color: #000000;">&#40;</span>i <span style="color: #000000; font-weight: bold;">+</span> <span style="color: #000000; font-weight:bold;">2</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #004993;">min</span>.z <span style="color: #000000; font-weight: bold;">?</span> myVertices<span style="color: #000000;">&#91;</span><span style="color: #004993;">int</span><span style="color: #000000;">&#40;</span>i <span style="color: #000000; font-weight: bold;">+</span> <span style="color: #000000; font-weight:bold;">2</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">min</span>.z;
&nbsp;
 		<span style="color: #004993;">max</span>.<span style="color: #004993;">x</span> = myVertices <span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #004993;">max</span>.<span style="color: #004993;">x</span> <span style="color: #000000; font-weight: bold;">?</span> myVertices <span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">max</span>.<span style="color: #004993;">x</span>;
		<span style="color: #004993;">max</span>.<span style="color: #004993;">y</span> = myVertices <span style="color: #000000;">&#91;</span><span style="color: #004993;">uint</span><span style="color: #000000;">&#40;</span>i <span style="color: #000000; font-weight: bold;">+</span> <span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #004993;">max</span>.<span style="color: #004993;">y</span> <span style="color: #000000; font-weight: bold;">?</span> myVertices<span style="color: #000000;">&#91;</span><span style="color: #004993;">int</span><span style="color: #000000;">&#40;</span>i <span style="color: #000000; font-weight: bold;">+</span> <span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">max</span>.<span style="color: #004993;">y</span>;
		<span style="color: #004993;">max</span>.z = myVertices <span style="color: #000000;">&#91;</span><span style="color: #004993;">uint</span><span style="color: #000000;">&#40;</span>i <span style="color: #000000; font-weight: bold;">+</span> <span style="color: #000000; font-weight:bold;">2</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #004993;">max</span>.z <span style="color: #000000; font-weight: bold;">?</span> myVertices<span style="color: #000000;">&#91;</span><span style="color: #004993;">int</span><span style="color: #000000;">&#40;</span>i <span style="color: #000000; font-weight: bold;">+</span> <span style="color: #000000; font-weight:bold;">2</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">max</span>.z;
	<span style="color: #000000;">&#125;</span>
&nbsp;
	center = <span style="color: #0033ff; font-weight: bold;">new</span> Vector3D<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>myMax.<span style="color: #004993;">x</span> <span style="color: #000000; font-weight: bold;">+</span> myMin.<span style="color: #004993;">x</span><span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000; font-weight:bold;">2.0</span>, <span style="color: #000000;">&#40;</span>myMax.<span style="color: #004993;">y</span> <span style="color: #000000; font-weight: bold;">+</span> myMin.<span style="color: #004993;">y</span><span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000; font-weight:bold;">2.0</span>, <span style="color: #000000;">&#40;</span>myMax.z <span style="color: #000000; font-weight: bold;">+</span> myMin.z<span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000; font-weight:bold;">2.0</span><span style="color: #000000;">&#41;</span>;
        radius = <span style="color: #004993;">Math</span>.<span style="color: #004993;">max</span><span style="color: #000000;">&#40;</span>myMax.<span style="color: #004993;">x</span> <span style="color: #000000; font-weight: bold;">-</span> center.<span style="color: #004993;">x</span>, myMax.<span style="color: #004993;">y</span> <span style="color: #000000; font-weight: bold;">-</span> center.<span style="color: #004993;">y</span>, myMax.z <span style="color: #000000; font-weight: bold;">-</span> center.z,
		          center.<span style="color: #004993;">x</span> <span style="color: #000000; font-weight: bold;">-</span> myMin.<span style="color: #004993;">x</span>, center.<span style="color: #004993;">y</span> <span style="color: #000000; font-weight: bold;">-</span> myMin.<span style="color: #004993;">y</span>, center.z <span style="color: #000000; font-weight: bold;">-</span> myMin.z<span style="color: #000000;">&#41;</span>;	
&nbsp;
	<span style="color: #0033ff; font-weight: bold;">return</span> <span style="color: #0033ff; font-weight: bold;">new</span> BoundingSphere<span style="color: #000000;">&#40;</span>center, radius<span style="color: #000000;">&#41;</span>;
<span style="color: #000000;">&#125;</span></pre></div></div>

<h5>3. Point to plane distance</h5>
<p>The plane equation (ax + by + cz + d) can be stored as a Vector3D object. Indeed, the Vector3D implements x, y and z but also a w Number attribute. This last one is supposed to store the homogenous coordinate. Nonetheless, we can use those 4 Number attributes to store the (a, b, c, d) values that defines our plane equation.</p>
<p>In order to test whether a bounding volume is inside or outside the frustum, we must be able to compute the distance of this object to the plane. To do so, we use the dot product of the point with the plane normal (which must be normalized first) :</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> planeToPointDistance<span style="color: #000000;">&#40;</span>myPlane <span style="color: #000000; font-weight: bold;">:</span> Vector3D, myPoint <span style="color: #000000; font-weight: bold;">:</span> Vector3D<span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">return</span> myPlane.<span style="color: #004993;">x</span> <span style="color: #000000; font-weight: bold;">*</span> myPoint.<span style="color: #004993;">x</span> <span style="color: #000000; font-weight: bold;">+</span> myPlane.<span style="color: #004993;">y</span> <span style="color: #000000; font-weight: bold;">*</span> myPoint.<span style="color: #004993;">y</span> <span style="color: #000000; font-weight: bold;">+</span> myPlane.z <span style="color: #000000; font-weight: bold;">*</span> myPoint.z <span style="color: #000000; font-weight: bold;">+</span> myPlane.w;
<span style="color: #000000;">&#125;</span></pre></div></div>

<h5>4. The test function</h5>
<p>Now that our frustum and our bounding volumes are ready, we can add this little test function that checks whether an object is visible or not:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> testBoundingSphere<span style="color: #000000;">&#40;</span>myPlanes      <span style="color: #000000; font-weight: bold;">:</span> Vector.,
                                   mySphere      <span style="color: #000000; font-weight: bold;">:</span> BoundingSphere<span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Boolean</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">length</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">int</span> = myPlanes.<span style="color: #004993;">length</span>;
&nbsp;
	<span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #000000;">&#40;</span><span style="color: #6699cc; font-weight: bold;">var</span> i <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">uint</span> = <span style="color: #000000; font-weight:bold;">0</span>; i <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #004993;">length</span>; <span style="color: #000000; font-weight: bold;">++</span>i<span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">d</span> 	<span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = planeToPointDistance<span style="color: #000000;">&#40;</span>myPlanes<span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span><span style="color: #000000;">&#41;</span>;
&nbsp;
		<span style="color: #009900;">// bouding sphere is out of the frustum</span>
		<span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #004993;">d</span> <span style="color: #000000; font-weight: bold;">+</span> mySphere.radius <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight:bold;">0.0</span><span style="color: #000000;">&#41;</span>
			<span style="color: #0033ff; font-weight: bold;">return</span> <span style="color: #0033ff; font-weight: bold;">false</span>;
		<span style="color: #009900;">// bounding sphere is spanning</span>
		<span style="color: #0033ff; font-weight: bold;">else</span> <span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #004993;">d</span> <span style="color: #000000; font-weight: bold;">-</span> mySphere.radius <span style="color: #000000; font-weight: bold;">&lt;</span>= <span style="color: #000000; font-weight:bold;">0.0</span><span style="color: #000000;">&#41;</span>
			<span style="color: #0033ff; font-weight: bold;">return</span> <span style="color: #0033ff; font-weight: bold;">true</span>;
	<span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #009900;">// bounding sphere is inside the frustum</span>
	<span style="color: #0033ff; font-weight: bold;">return</span> <span style="color: #0033ff; font-weight: bold;">true</span>;
<span style="color: #000000;">&#125;</span></pre></div></div>

<h4>The Experiment</h4>
<p>The following experiment demonstrates frustum culling in action (click on the picture to open the application) :</p>
<div id="attachment_560" class="wp-caption aligncenter" style="width: 510px"><a rel="shadowbox[tekkaman];width=500;height=375]" href="http://blog.promethe.net/wp-content/uploads/2009/12/Tekkaman.swf"><img class="size-full wp-image-560" title="frustum_culling" src="http://blog.promethe.net/wp-content/uploads/2009/12/frustum_culling.png" alt="frustum_culling" width="500" height="375" /></a><p class="wp-caption-text">Frustum culling experiment (use the arrow keys to move)</p></div>
<p style="text-align: left;">Use the arrow keys to move the robot across the scene. You can notice the TPS counter drops down to zero whenever the character is out of sight (on the near left or near right side of the screen). When the TPS indicates 0, no triangles are rendered and CPU usage drops down to 0%. It actually means that the rest of the rendering process has a minimal overhead!</p>
<h4>And it's even more awesome...</h4>
<p style="text-align: left;">This experiment also introduce my brand new mini-debugger inspired of <a href="http://mrdoob.com/80/Stats">Mr. Doob's work</a>. I replaced the maximum memory footprint counter with a per-second rendered triangles counter (or TPS counter). CPU usage or framerate alone are not absolute measurements but the TPS counter reflects the true performance of the application the old fashioned way: the more polygons per second the better. I also updated the timer to display the processing time and the overall rendering time.</p>
<p style="text-align: left;">You can compare this experiment to the <a href="http://blog.promethe.net/2009/10/07/quake-2-3d-models-in-flash-10/">"old" one I made up a few weeks ago</a>: the displayed 3D model features 30% more polygons but the CPU usage is the same.</p>
<p style="text-align: left;">The rendering process is done in such a way that absolutely no computation occurs on invisible objects, not even the slightest animation or z-sorting operation.</p>
<p style="text-align: left;">I enabled dynamic bounding volumes for animated meshes: if you place the mesh on the edges of the viewing space, you might notice that the TPS counter sometimes goes down to zero to raise up again to a few hundreds/thousands of triangles per second. The explanation is simple: the visibility test is done dynamically and follows the mesh animations. If the animation drives the mesh out of the viewing frustum, culling operates and it is not renderered.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.promethe.net/2009/12/13/frustum-culling-in-flash-10/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>MadCompany: Coming Soon!</title>
		<link>http://blog.promethe.net/2009/12/10/madcompany-coming-soon/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=madcompany-coming-soon</link>
		<comments>http://blog.promethe.net/2009/12/10/madcompany-coming-soon/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 23:05:04 +0000</pubDate>
		<dc:creator>Promethe</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[ActionScript 3.0]]></category>
		<category><![CDATA[Augmented Reality]]></category>
		<category><![CDATA[FLARToolkit]]></category>
		<category><![CDATA[Flash 10]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://blog.promethe.net/?p=554</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><center><br />
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/wrfLwa1aXrI&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/wrfLwa1aXrI&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br />
</center></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.promethe.net/2009/12/10/madcompany-coming-soon/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Augmented Reality in Flash 10</title>
		<link>http://blog.promethe.net/2009/10/20/augmented-reality-in-flash-10/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=augmented-reality-in-flash-10</link>
		<comments>http://blog.promethe.net/2009/10/20/augmented-reality-in-flash-10/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 19:55:46 +0000</pubDate>
		<dc:creator>Promethe</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[3DS]]></category>
		<category><![CDATA[Augmented Reality]]></category>
		<category><![CDATA[FLARToolkit]]></category>
		<category><![CDATA[Flash 10]]></category>

		<guid isPermaLink="false">http://blog.promethe.net/?p=496</guid>
		<description><![CDATA[For those who have never heard of "augmented reality" (AR), here is Wikipedia's definition: Augmented reality (AR) is a term for a live direct or indirect view of a physical real-world environment whose elements are merged with (or augmented by) virtual computer-generated imagery - creating a mixed reality. Sounds a bit blury? Well... I'll try [...]]]></description>
			<content:encoded><![CDATA[<p>For those who have never heard of "augmented reality" (AR), here is <a href="http://en.wikipedia.org/wiki/Augmented_reality" target="_target">Wikipedia</a>'s definition:</p>
<blockquote><p>Augmented reality (AR) is a term for a live direct or indirect view of a physical real-world environment whose elements are merged with (or augmented by) virtual computer-generated imagery - creating a mixed reality.</p></blockquote>
<p>Sounds a bit blury? Well... I'll try to make it clearer with a demo...</p>
<h4>Demo</h4>
<p>First, you will have to print a little black and white "marker". The AR software scans the webcam picture and look for this very marker. When it is found, its 3D position, rotation and scale are computed and used to embed a 3D object. You can found the marker <a href="http://blog.promethe.net/wp-content/uploads/2009/10/flarlogo-marker.pdf" target="_blank">here</a> and it looks like this:</p>
<div id="attachment_517" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.promethe.net/wp-content/uploads/2009/10/flarlogo_marker.jpg" rel="shadowbox[post-496];player=img;"><img class="size-full wp-image-517" title="flarlogo_marker" src="http://blog.promethe.net/wp-content/uploads/2009/10/flarlogo_marker.jpg" alt="FLARToolkit Marker" width="300" height="300" /></a><p class="wp-caption-text">FLARToolkit Marker</p></div>
<p><span id="more-496"></span></p>
<p>Then, launch the following application and place the printed marker in front of your camera:</p>
<div id="attachment_505" class="wp-caption aligncenter" style="width: 330px"><a rel="shadowbox[minkoflar];width=640;height=480" href="http://blog.promethe.net/wp-content/uploads/2009/10/MinkoFLARDemo.swf"><img class="size-full wp-image-505" title="FLARToolkit in Flash 10" src="http://blog.promethe.net/wp-content/uploads/2009/10/minkoflar_tekkaman.jpg" alt="FLARToolkit in Flash 10" width="320" height="240" /></a><p class="wp-caption-text">FLARToolkit demo application (webcam required)</p></div>
<h4>What it does...</h4>
<ul>
<li>Load a <a href="http://blog.promethe.net/2009/10/07/quake-2-3d-models-in-flash-10/">MD2 file</a> and a JPEG texture</li>
<li>Loop through the animation of the model</li>
<li>Define multiple materials (press "w" to switch)</li>
<li>Use the <a href="http://www.libspark.org/wiki/saqoosha/FLARToolKit/en" target="_blank">FLARToolkit</a> library for the AR</li>
<li>Translate FLARToolkit matrices to fit the 3D API</li>
</ul>
<h4>How it works</h4>
<ul>
<li>The viewport and a dummy camera are initialized using the camera parameters and the size of the capture</li>
<li>The webcam image is binarized using a threshold filter: aeras that are darker than a threshold value end up completely white on a black background. Areas that are too small or too big are rejected.</li>
<li>Each remaining area is detected and its bounding box and position are computed</li>
<li>For each area that "looks like" a square, the data of what should be the pattern is extracted</li>
<li>This data is then compared to the actual pattern</li>
<li>If the match confidence is above a certain value (80% is this case), a matrix that contains the position/rotation/scale of the center of the marker is computed</li>
<li>This matrix is converted into a native Matrix3D object that can be used as the world transform for the 3D objects we want to display</li>
</ul>
<h4>What it does not do...</h4>
<ul>
<li>Use FLARManager to handle the AR. Lee "<a href="http://theflashblog.com/" target="_blank">The Flash Blog</a>" Brimelow juste made this <a href="http://gotoandlearn.com/play?id=114" target="_blank">excellent tutorial</a> about FLARManager: thank you Lee!</li>
</ul>
<h4>Known Issues</h4>
<p>The FLARToolkit library is very CPU intensive! I looked into it and beside the fact that it is poorly engineered, it looks like the blob extraction algorithm is the bottleneck. Sadly, there is not much to do about it...</p>
<p>It was ported from a Java port of a C++ library called ARToolkit. I never read the original C++ code or its Java port, but the AS3 version seems to be just a straight forward rewriting without much thinking. AS3 native types are totally ignored, if not re-implemented, and the design clearly perspires C++ (and not only because the original code is embeded in comments all over the place...). FLARManager apparently leverages the lack of a proper API.</p>
<p>To put it in a nutshell, FLARToolkit is an impressive tool but it needs a big cleanup!</p>
<h4>Credits</h4>
<ul>
<li><a href="http://mrdoob.com/80/Hi-ReS!_Stats" target="_blank">Framerate counter</a> by <a href="http://mrdoob.com" target="_blank">Mr. Doob</a></li>
<li>Augmented reality using <a href="http://www.libspark.org/wiki/saqoosha/FLARToolKit/en" target="_blank">FLARToolkit</a> by <a href="http://saqoosha.net/en/" target="_blank">Saqoosha</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.promethe.net/2009/10/20/augmented-reality-in-flash-10/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Quake 2&#8242;s 3D models in Flash 10</title>
		<link>http://blog.promethe.net/2009/10/07/quake-2-3d-models-in-flash-10/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=quake-2-3d-models-in-flash-10</link>
		<comments>http://blog.promethe.net/2009/10/07/quake-2-3d-models-in-flash-10/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 12:42:28 +0000</pubDate>
		<dc:creator>Promethe</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[experiment]]></category>
		<category><![CDATA[Flash 10]]></category>
		<category><![CDATA[Quake 2]]></category>

		<guid isPermaLink="false">http://blog.promethe.net/?p=428</guid>
		<description><![CDATA[Loading and rendering Quake 2's maps is a challenge because Flash 10 doesn't handle complex 3D geometry very well. But what about a smaller count of polygons ? Say a 3D model for example... already done! What about an animated 3D model then? Details, pictures and a demo application right after the jump... MD2 file [...]]]></description>
			<content:encoded><![CDATA[<p>Loading and rendering Quake 2's maps is a challenge because Flash 10 doesn't handle complex 3D geometry very well. But what about a smaller count of polygons ? Say a 3D model for example... already done! What about an animated 3D model then?</p>
<p><strong>Details, pictures and a demo application right after the jump...</strong></p>
<p><span id="more-428"></span></p>
<h4>MD2 file format</h4>
<p>Quake 2 uses the MD2 file format  to store animated 3D models. It is a quite simple file format: each MD2 file stores a single mesh and its animations. Each animation is just copy of the original mesh with different positions for each vertex. The number of vertices and the indices are the same for each frame. Therefore, the MD2 file format is easy to adapt to the Flash Platform because no complicated shaders/bones are required to animate the model: you just have to display the right vertices!</p>
<p>But it is not THAT simple. Each animation is actually subdivided into frames (vertices really). Because storing a fluid animation would take a lot of frames (and a lot of memory), only a few keyframes are stored. When rendering, one must compute the interpolation coefficient between the current and the next keyframe and use it to get the interpolated vertices. The following code does it all:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> frame1	<span style="color: #000000; font-weight: bold;">:</span> Vector.<span style="color: #000000; font-weight: bold;">&lt;</span>Number<span style="color: #000000; font-weight: bold;">&gt;</span>	= _currentFrame.vertices;
<span style="color: #6699cc; font-weight: bold;">var</span> frame2	<span style="color: #000000; font-weight: bold;">:</span> Vector.<span style="color: #000000; font-weight: bold;">&lt;</span>Number<span style="color: #000000; font-weight: bold;">&gt;</span>	= _nextFrame.vertices;
<span style="color: #6699cc; font-weight: bold;">var</span> c2		<span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span>		= _frame <span style="color: #000000; font-weight: bold;">-</span> <span style="color: #004993;">int</span><span style="color: #000000;">&#40;</span>_frame<span style="color: #000000;">&#41;</span>;
<span style="color: #6699cc; font-weight: bold;">var</span> c1		<span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span>		= <span style="color: #000000; font-weight:bold;">1</span> <span style="color: #000000; font-weight: bold;">-</span> c2;
<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">length</span>	<span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span>		= frame1.<span style="color: #004993;">length</span>;
&nbsp;
<span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #000000;">&#40;</span><span style="color: #6699cc; font-weight: bold;">var</span> i <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">uint</span> = <span style="color: #000000; font-weight:bold;">0</span>; i <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #004993;">length</span>; <span style="color: #000000; font-weight: bold;">++</span>i<span style="color: #000000;">&#41;</span>
	_vertices<span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span> = frame1<span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">*</span> c1 <span style="color: #000000; font-weight: bold;">+</span> frame2<span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span> <span style="color: #000000; font-weight: bold;">*</span> c2;</pre></div></div>

<p>... and here is the demo application :</p>
<div id="attachment_475" class="wp-caption aligncenter" style="width: 510px"><a rel="shadowbox[q2];width=500;height=375" href="http://blog.promethe.net/wp-content/uploads/2009/10/MinkoMD2Demo.swf"><img class="size-full wp-image-475" title="minko_q2_brianna" src="http://blog.promethe.net/wp-content/uploads/2009/10/minko_q2_brianna.jpg" alt="minko_q2_brianna" width="500" height="375" /></a><p class="wp-caption-text">Flash 10 MD2 loader</p></div>
<p style="text-align: center;">
<h4>What it does...</h4>
<ul>
<li>load Quake 2's MD2 files</li>
<li>basic z-sorting using faces barycenter</li>
<li>add a "frame" property to the mesh to handle animations</li>
<li>interpolate and update vertices only when necessary</li>
<li>wireframe material (press "w")</li>
<li>"free chase" camera (mouse click + drag'n'drop to turn around the model)</li>
</ul>
<h4>What it doesn't do...</h4>
<ul>
<li>use BSP trees to handle z-sorting (1 BSP tree / frame takes a lot of time and memory...)</li>
<li>loop through a specific animation</li>
<li>read Quake 2's animation files</li>
</ul>
<h4>Known issue(s)</h4>
<p>None. If you find one please let me know! Performance seems to be very good actually...</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.promethe.net/2009/10/07/quake-2-3d-models-in-flash-10/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Load and display Quake 2&#8242;s Maps in Flash 10</title>
		<link>http://blog.promethe.net/2009/10/01/load-and-display-quake-2s-maps-in-flash-10/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=load-and-display-quake-2s-maps-in-flash-10</link>
		<comments>http://blog.promethe.net/2009/10/01/load-and-display-quake-2s-maps-in-flash-10/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 17:37:26 +0000</pubDate>
		<dc:creator>Promethe</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Flash 10]]></category>
		<category><![CDATA[Game]]></category>
		<category><![CDATA[Quake 2]]></category>

		<guid isPermaLink="false">http://blog.promethe.net/?p=433</guid>
		<description><![CDATA[The Quake-series is really awesome. Not only in terms of gameplay but also technically. Quake 1, 2 and 3 are especially impressive. No wonder why Quake's graphics engine, maps or models file formats have been reused in many many games such as Half Life, Call of Duty or Medal of Honnor! So why not in [...]]]></description>
			<content:encoded><![CDATA[<p>The <strong>Quake-series is really awesome</strong>. Not only in terms of gameplay but also <strong>technically</strong>. Quake 1, 2 and 3 are especially impressive. No wonder why Quake's graphics engine, maps or models file formats have been reused in many many games such as <strong>Half Life</strong>, <strong>Call of Duty</strong> or <strong>Medal of Honnor</strong>! So why not in your own Flash 10 game?</p>
<p>There are so many reasons why loading Quake 2 files inside the Flash player would be considered as just "impossible". Performance would be the first and main one. One would just consider that Flash is not fast enough to display complex 3D graphics, not even those of a game as old as Quake 2 (published in 1996!). But using Flash 10 latests features such as the Vector and GraphicsTrianglePath classes, it is actually quite doable!</p>
<p><strong>Details, pictures and a demo application right after the jump!</strong></p>
<p><span id="more-433"></span></p>
<h4>Quake 2's maps file format</h4>
<p>But the really big advantage here is inside the Quake 2 maps file format itself. Each map is a *.BSP file and the BSP file format might be the best ratio in terms of ease of implementation against performance optimization. As you might have guessed, *.BSP files actually store a pre-compiled <a href="http://en.wikipedia.org/wiki/Binary_space_partitioning" target="_blank">Binary Space Partitionning</a> tree of the map itself. For those who don't already know about BSP trees, just imagine that it is actually the best known method to handle a polygon-perfect z-sorting in Flash when dealing with 3D. But computing a good BSP tree of a large and complex 3D model such as a map takes a lot of time... that is why having a pre-compiled and ready to load BSP tree is just great!</p>
<p>You can find a lot of good documents on the Quake 2 BSP file format. The one hosted on <a href="http://www.flipcode.com/archives/Quake_2_BSP_File_Format.shtml" target="_blank">flipcode</a> is quite complete and easy to understand. It is actually the one I used to create my BSP loader. Reading the file formats specifications shows that *.BSP files also include "visibility information". This data is also very important because it makes the user able to know which area of the map is visible from any other area. This way, only the areas visible from the area where the player stands have to be displayed which is an incredible performance boost!</p>
<p>The following application is a proof of concept of a Flash powered Quake 2 *.BSP loader :</p>
<div id="attachment_434" class="wp-caption aligncenter" style="width: 508px"><a rel="shadowbox[quake2_proof];width=500;height=375" href="http://blog.promethe.net/wp-content/uploads/2009/10/MinkoQuake2BSPTest.swf"><img class="size-full wp-image-434" title="quake2_bsp_proof" src="http://blog.promethe.net/wp-content/uploads/2009/10/quake2_bsp_proof.jpg" alt="quake2_bsp_proof" width="498" height="373" /></a><p class="wp-caption-text">Click on the picture to launch the demo application.</p></div>The application weights 174Ko because the *.BSP file is embed in it. With the map file as an external resource, the application weights only 20Ko! The map is called ''q264_3.bsp" and can be found on Google. It is not an actual Quake 2 map but a fan made map.</p>
<p>Here are some screenshots of the same application loading much more complex maps (those screenshots have been made with the Flash debugger which explains the higher memory consumption) :</p>
<p><div id="attachment_456" class="wp-caption aligncenter" style="width: 510px"><a href="http://blog.promethe.net/wp-content/uploads/2009/10/quake2_actcity2.jpg" rel="shadowbox[post-433];player=img;"><img class="size-full wp-image-456" title="quake2_actcity2" src="http://blog.promethe.net/wp-content/uploads/2009/10/quake2_actcity2.jpg" alt="quake2_actcity2" width="500" height="375" /></a><p class="wp-caption-text">actcity2</p></div>
<div id="attachment_457" class="wp-caption aligncenter" style="width: 510px"><a href="http://blog.promethe.net/wp-content/uploads/2009/10/quake2_aqnitro.jpg" rel="shadowbox[post-433];player=img;"><img class="size-full wp-image-457" title="quake2_aqnitro" src="http://blog.promethe.net/wp-content/uploads/2009/10/quake2_aqnitro.jpg" alt="aqnitro" width="500" height="375" /></a><p class="wp-caption-text">aqnitro</p></div>
<h4>What it does...</h4>
<ul>
<li>load Quake 2's *.BSP files</li>
<li>build the corresponding geometry (vertices, indices and UV data) using Flash 10 native types such as Vector and GraphicsTrianglePath</li>
<li>frustum culling and clipping using bounding boxes and bounding spheres</li>
<li>mouse controlled "free chase" camera (click + drag'n'drop to look around, mouse wheel to zoom in/out)</li>
</ul>
<h4>What's next...</h4>
<ul>
<li>use the embed BSP data to handle z-sorting</li>
<li>use visibility information to display only visible clusters</li>
<li>load WAL textures (Quake 1 and 2 textures file format, already done just have to post it <img src='http://blog.promethe.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> )  and use them properly to display the map</li>
<li>load MD2 animated 3D models (again, already done and just have to post it!)</li>
</ul>
<h4>Known issue(s)</h4>
<p>If you zoom enough to place the camera "inside" the map geometry, you will notice a severe framerate drop down. It is very logical since frustum clipping will have to check and eventually clip each polygon of the geometry against the relevant view frustum planes. Because visibility information tells us what is actually visible or not, handling it properly should offer a huge performance boost: instead of having to clip the whole geometry, only the visible areas will be treated.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.promethe.net/2009/10/01/load-and-display-quake-2s-maps-in-flash-10/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>New DirectFlex experiments: &#8216;FPS&#8217; and &#8216;Earth&#8217;</title>
		<link>http://blog.promethe.net/2009/06/12/new-directflex-experiments/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=new-directflex-experiments</link>
		<comments>http://blog.promethe.net/2009/06/12/new-directflex-experiments/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 11:16:58 +0000</pubDate>
		<dc:creator>Promethe</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[DirectFlex]]></category>
		<category><![CDATA[experiment]]></category>
		<category><![CDATA[Flash 10]]></category>

		<guid isPermaLink="false">http://blog.promethe.net/?p=337</guid>
		<description><![CDATA[I just posted and blogged about a few new experiments built using DirectFlex on Direct Flex Labs: FPS: is it possible to display Half Life 1 graphics in Flash ? I don't know yet... but this experiment is an improvement of the one I posted a while back Earth: I always wanted to implement the [...]]]></description>
			<content:encoded><![CDATA[<p>I just posted and blogged about a few new experiments built using <a href="http://blog.directflex.net/" target="_blank">DirectFlex</a> on <a href="http://labs.directflex.net" target="_blank">Direct Flex Labs</a>:</p>
<ul>
<li><a href="http://labs.directflex.net/experiment/view?id=4" target="_blank">FPS</a>: is it possible to display Half Life 1 graphics in Flash ? I don't know yet... but this experiment is an improvement of <a href="http://blog.promethe.net/2008/12/24/display-half-life-3d-models-with-flash-10/">the one I posted a while back</a></li>
<li><a href="http://labs.directflex.net/experiment/view?id=7" target="_blank">Earth</a>: I always wanted to implement the famous Google Earth in Flash. This might be a good first step! I made this experiment in approximately 1 hour to test out a few new features</li>
</ul>
<p>Please let me know what you think about those new experiments. Any feedback will be greatly appreciated!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.promethe.net/2009/06/12/new-directflex-experiments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
